16

是否可以同时组合 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# 编译器的错误或缺失功能?

4

3 回答 3

28

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

Anobject-initializer由多个member-initializers 组成,每个 s 的形式为,initializer = initializer-value而 acollection-initializer由多个element-initializers 组成,每个 s 为 a 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 } };
于 2011-06-06T15:20:10.717 回答
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>. 请参阅:继承 List<T> 来实现集合是个坏主意?

于 2011-06-06T15:20:34.590 回答
2

如果您想获得类似的功能,请考虑创建一个构造函数参数:

var x = new CustomList("Hello World") { 1, 2, 3 }
于 2011-06-06T15:30:19.173 回答