组合列表初始值设定项和对象初始化项
可以同时组合一个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 };
这是由设计或只是一个bug或C#编译器功能缺失?
否,从C#规范的部分7.6.10看的定义,一个object-or-collection-initializer
表达是要么一个object-initializer
或一个collection-initializer
。
的object-initializer
是由多个的member-initializer
S,其中的每一个的形式initializer = initializer-value
的而collection-initializer
由多个的element-initializer
S,其中的每一个是一个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 } };
不,它是不是一个错误。它是通过语言的设计。
当你写
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?
如果你想要得到的东西像这样的功能,考虑制定构造函数的参数:
var x = new CustomList("Hello World") { 1, 2, 3 }
但是在我有很多参数的情况下,但在大多数情况下只想设置它们中的几个的情况下,这不会是最好的解决方案 – codymanix 2011-06-06 15:49:10
该规范应该强制对象初始化部分和列表初始化部分此起彼伏,而不是交错:) – codymanix 2011-06-06 15:52:59
@codymanix:查看我的编辑方法。 – 2011-06-06 16:00:57
你还需要一套。 – Tejs 2011-06-06 18:10:23