组合List初始化器和对象初始化器

时间:2011-06-06 15:16:50

标签: c# .net object-initializers collection-initializer

是否可以同时组合List初始值设定项和对象初始值设定项? 给出以下类定义:

class MyList : List<int>
{
    public string Text { get; set; }
}

// we can do this
var obj1 = new MyList() { Text="Hello" };

// we can also do that
var obj2 = new MyList() { 1, 2, 3 };

// but this one doesn't compile
//var obj3 = new MyList() { Text="Hello", 1, 2, 3 };

这是设计还是只是c#编译器的错误或遗漏功能?

3 个答案:

答案 0 :(得分:26)

不,查看C#规范第7.6.10节中的定义,object-or-collection-initializer表达式 object-initializer a collection-initializer

object-initializer由多个member-initializer组成,每个initializer = initializer-value的形式为collection-initializer,而element-initializer由多个non-assigment-expression组成,每个都是List<int>

所以看起来它是设计的 - 可能是为了简单起见。说实话,我不能说我曾经想要这样做。 (我通常不会从var obj3 = new MyList { 1, 2, Text = "Hello", 3, 4 }; 派生出来 - 我会把它组成。)我真的很讨厌看到:

class MyList : List<int>
{
    public string Text { get; set; }
    public MyList Values { get { return this; } }
}

编辑:如果你真的,真的想要启用它,你可以把它放在课堂上:

var obj3 = new MyList { Text = "Hello", Values = { 1, 2, 3, 4 } };

此时你可以写:

{{1}}

答案 1 :(得分:3)

不,这不是一个错误。它是按语言设计的。

写作时

var obj1 = new MyList() { Text="Hello" };

编译器将其有效地翻译为

MyList temp = new MyList();
temp.Text = "Hello";
MyList obj = temp;

写作时

var obj2 = new MyList() { 1, 2, 3 };

编译器将其有效地翻译为

MyList temp = new MyList();
temp.Add(1);
temp.Add(2);
temp.Add(3);
MyList obj2 = temp;

请注意,在第一种情况下,您使用的是对象初始值设定项,但在第二种情况下,您使用的是集合初始值设定项。没有对象和集合初始化器这样的东西。您要么初始化对象的属性,要么初始化集合。你不能两者兼顾,这是设计的。

此外,您不应该从List<T>派生。请参阅:Inheriting List<T> to implement collections a bad idea?

答案 2 :(得分:2)

如果你想获得类似这个功能的东西,可以考虑创建一个构造函数参数:

var x = new CustomList("Hello World") { 1, 2, 3 }