对象初始化和“命名构造函数成语”

时间:2009-03-06 21:26:17

标签: c# .net object-initializers

确定。所以我有一个值列表,我想做类似以下的事情:

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

所以这就是问题所在。我需要上面的例子来使用命名构造函数,例如:

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

我有什么方法可以做到吗?基本上,我需要调用一个静态方法来获取对象实例,我想按上面的方式初始化它。

编辑:我目前没有简单的方法来修改MyType的界面,所以添加新的函数调用(虽然可能是'最佳'方法)目前还不太实用。

3 个答案:

答案 0 :(得分:2)

我确信有人会想到在4.0 C#中做到这一点的聪明方法,但我刚看了Sam Ng's blog post on named parameters in C# 4.0。这应该可以解决您的问题。它看起来像这样:

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

修改

Fogot提到,使这个有用的是你可以设置参数的默认值,所以你不必全部传递它们。博客文章是一个很好的简短摘要。

答案 1 :(得分:1)

更新:工厂怎么样:

MyObjectValues.Select(currentItems=>MyTypeFactory.GetNewInstance(currentItems.Value1,
currentItems.Value2));


public static class MyTypeFactory
{
    public static MyType GetNewInstance(
         typeofvalue1 value1, 
         typeofvalue2 value2)
    {
        return new MyType { Parameter1 = value1, Parameter2 = value2 };
    }
}

答案 2 :(得分:1)

不幸的是,在C#3.0中没有直接的支持。对象初始值设定项仅 支持构造函数调用。但是,您可以考虑使用Builder模式。在我的Protocol Buffers端口中,我支持它:

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

所以你的例子会变成:

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

当然,这意味着编写嵌套的Builder类型,但它可以很好地工作。如果你不介意MyType 严格来说可变,你可以保留一个不可变的API,但是让Builder的实例立即创建一个MyType的新实例,然后设置属性因为它(因为它可以访问私有成员),然后最终在MyType方法中返回Build()的实例。 (然后它应该“忘记”实例,以便禁止进一步的突变。)