1

行。所以我有一个值列表,我想做如下的事情:

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

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

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

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

编辑:目前我没有一种简单的方法来修改 MyType 的接口,因此添加新的函数调用(虽然可能是“最好的”方法)目前不是很实用。

4

3 回答 3

2

我敢肯定,有人会在 C# 4.0 之前的版本中想到一个聪明的方法,但我刚刚阅读了Sam Ng 的关于 C# 4.0 中命名参数的博客文章。这应该可以解决您的问题。它看起来像这样:

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

编辑

忘了提一下,它的有用之处在于您可以为参数设置默认值,因此您不必全部传递它们。博客文章是一个很好的简短摘要。

于 2009-03-06T21:30:54.830 回答
2

不幸的是,在 C# 3.0 中没有对此的直接支持。对象初始化器支持构造函数调用。但是,您可能会考虑 Builder 模式。在我的协议缓冲区端口中,我支持它是这样的:

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()。(然后它应该“忘记”该实例,从而禁止进一步的突变。)

于 2009-03-06T21:34:53.230 回答
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 };
    }
}
于 2009-03-06T21:33:36.103 回答