Combining List initializer and object initializer
是否可以同时组合列表初始值设定项和对象初始值设定项?给定以下类定义:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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编译器的一个缺陷或缺失的特性?
不,从C规范第7.6.10节的定义来看,object-or-collection-initializer表达式要么是object-initializer要么是collection-initializer。
object-initializer由多个member-initializer组成,每个initializer = initializer-value的形式,而collection-initializer由多个element-initializer组成,每个non-assigment-expression的形式。
所以它看起来像是设计出来的——可能是为了简单。老实说,我从来没想过要这么做。(我通常不会从List开始——我会改为作曲。)我真的不想看到:
1
| var obj3 = new MyList { 1, 2, Text ="Hello", 3, 4 }; |
编辑:如果你真的,真的想启用这个,你可以把它放在类中:
1 2 3 4 5
| class MyList : List<int>
{
public string Text { get; set; }
public MyList Values { get { return this; } }
} |
这时你可以写:
1
| var obj3 = new MyList { Text ="Hello", Values = { 1, 2, 3, 4 } }; |
- 规范应强制对象初始值设定项部分和列表初始值设定项部分一个接一个且不交错:)
- @科迪马尼克斯:看看我的编辑。
- 你还需要一套。
- @Tejs:不,你不会的。它使用的是嵌入的集合初始值设定项。
- 我是不是错过了什么?这个说法等同于var x = new MyList(); x.Text ="Hello"; x.Values = new List { 1, 2, 3, 4 }?好像你需要一套。
- @不,不是…你在哪里看到它创造了一个新的List?这(主要)就像是说var x = new MyList(); x.Text ="Hello"; x.Values.Add(1); x.Values.Add(2); ...试试看:)
- 啊,我不好。我忘记了集合初始值设定项只是调用Add方法。
- @乔恩·斯基特:一个有趣的想法是让一个财产回归自己:)
- @jon:msmvps.com/blogs/jonskeet/archive/2013/02/14/&hellip;提供更多乐趣。
不,这不是虫子。这是语言的设计。
当你写作时
1
| var obj1 = new MyList () { Text ="Hello" }; |
编译器有效地将其翻译为
1 2 3
| MyList temp = new MyList ();
temp .Text ="Hello";
MyList obj = temp ; |
当你写作时
1
| var obj2 = new MyList () { 1, 2, 3 }; |
编译器有效地将其翻译为
1 2 3 4 5
| MyList temp = new MyList ();
temp .Add(1);
temp .Add(2);
temp .Add(3);
MyList obj2 = temp ; |
注意,在第一种情况下,您使用的是对象初始值设定项,而在第二种情况下,您使用的是集合初始值设定项。没有对象和集合初始化器这样的东西。您正在初始化对象的属性,或者正在初始化集合。你不能两者兼得,这是按设计的。
另外,你不应该从List中得到。请参见:继承list以实现集合是一个坏主意?
- 我知道它是怎么翻译的。我看不出我们为什么不能把第一个和第二个结合起来。
- @Codymanix:因为它不在语言规范中。
- 我很想知道为什么这次被否决。
- 那不是我:
如果要获得类似于此功能的内容,请考虑生成一个构造函数参数:
1
| var x = new CustomList ("Hello World") { 1, 2, 3 } |
- 但是在我有很多论点,但大多数情况下只想设置其中的一部分的情况下,这不是最好的解决方案。