Search code examples
c#.netobject-initializers

Object Initialization and "Named Constructor Idiom"


Ok. So I have a list of values, and I'd like to do something like the following:

MyObjectValues
.Select(currentItems=>new MyType()
{
     Parameter1 = currentItems.Value1,
     Parameter2 = currentItems.Value2
});

So here's the problem. I need the above example to work with named constructors, such as:

MyObjectValues
.Select(currentItems=>MyType.GetNewInstance()
{
     Parameter1 = currentItems.Value1,
     Parameter2 = currentItems.Value2
});

Is there any way I can do that? Basically, I have a static method I need to call to get the object instance back, and I'd like to initialize it as above.

EDIT: I don't have an easy way to modify the interface of MyType at present, so adding new function calls (while probably the 'best' approach) isn't very practical at the moment.


Solution

  • Unfortunately there's no direct support for this in C# 3.0. Object initializers are only supported for constructor calls. However, you might consider the Builder pattern. In my Protocol Buffers port, I support it like this:

    MyType foo = new MyType.Builder {Parameter1 = 10, Parameter2 = 20}.Build();
    

    So your example would become:

    MyObjectValues.Select(currentItems => new MyType.Builder
    {
         Parameter1 = currentItems.Value1,
         Parameter2 = currentItems.Value2
    }.Build());
    

    Of course, it means writing the nested Builder type, but it can work quite well. If you don't mind MyType being strictly speaking mutable, you can leave an immutable API but make an instance of Builder immediately create a new instance of MyType, then set properties as it goes (as it has access to private members), and then finally return the instance of MyType in the Build() method. (It should then "forget" the instance, so that further mutation is prohibited.)