正在组合列表初始化项和对象初始化项

本文关键字:初始化 对象 列表 组合 | 更新日期: 2023-09-27 17:58:41

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

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#编译器的一个bug或缺失的功能?

正在组合列表初始化项和对象初始化项

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

object-initializer由多个member-initializers组成,每个CCD_5s的形式为initializer = initializer-value,而collection-initializer由多个CCD _8s组成,每个都为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 } };
不,这不是一个bug。它是由语言设计的。

当你写

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>派生。请参阅:继承列表<T>实现集合是个坏主意吗?

如果你想获得类似的功能,可以考虑制作一个构造函数参数:

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