是否可以同时组合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#编译器的错误或遗漏功能?
答案 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 }