简体   繁体   English

组合列表初始化器和 object 初始化器

[英]Combining List initializer and object initializer

Is is possible to combine a List initializer and object initializer at the same time?是否可以同时组合 List 初始化程序和 object 初始化程序? Given the following class definition:给定以下 class 定义:

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 };

Is this by design or is it just a bug or missing feature of the c# compiler?这是设计使然,还是只是 c# 编译器的错误或缺失功能?

No, looking at the definitions from section 7.6.10 of the C# spec, an object-or-collection-initializer expression is either an object-initializer or a collection-initializer .不,查看 C# 规范第 7.6.10 节中的定义, object-or-collection-initializer表达式object-initializercollection-initializer

An object-initializer is composed of multiple member-initializer s, each of which is of the form initializer = initializer-value whereas a collection-initializer is composed of multiple element-initializer s, each of which is a non-assigment-expression .一个object-initializer由多个member-initializer组成,每个 member-initializer 的形式为initializer = initializer-valuecollection-initializer由多个element-initializer组成,每个 element-initializer 都是一个non-assigment-expression

So it looks like it's by design - possibly for the sake of simplicity.所以它看起来像是设计的——可能是为了简单起见。 I can't say I've ever wanted to do this, to be honest.老实说,我不能说我曾经想过这样做。 (I usually wouldn't derive from List<int> to start with - I'd compose it instead.) I would really hate to see: (我通常不会从List<int>派生 - 我会编写它。)我真的不想看到:

var obj3 = new MyList { 1, 2, Text = "Hello", 3, 4 };

EDIT: If you really, really want to enable this, you could put this in the class:编辑:如果你真的,真的想启用它,你可以把它放在 class 中:

class MyList : List<int>
{
    public string Text { get; set; }
    public MyList Values { get { return this; } }
}

at which point you could write:此时你可以写:

var obj3 = new MyList { Text = "Hello", Values = { 1, 2, 3, 4 } };

No, it's a not a bug.不,这不是错误。 It is by design of the language.这是语言的设计。

When you write当你写

var obj1 = new MyList() { Text="Hello" };

this is effectively translated by the compiler to这被编译器有效地翻译成

MyList temp = new MyList();
temp.Text = "Hello";
MyList obj = temp;

When you write当你写

var obj2 = new MyList() { 1, 2, 3 };

this is effectively translated by the compiler to这被编译器有效地翻译成

MyList temp = new MyList();
temp.Add(1);
temp.Add(2);
temp.Add(3);
MyList obj2 = temp;

Note that in the first case you are using an object initializer, but in the second case you are using a collection initializer.请注意,在第一种情况下,您使用的是 object 初始化程序,但在第二种情况下,您使用的是集合初始化程序。 There is no such thing as an object-and-collection intializer.没有对象和集合初始化器之类的东西。 You are either initializing the properties of your object, or you are initializing the collection.您正在初始化 object 的属性,或者正在初始化集合。 You can not do both, this is by design.你不能两者都做,这是设计使然。

Also, you shouldn't derive from List<T> .此外,您不应该从List<T>派生。 See: Inheriting List<T> to implement collections a bad idea?请参阅: 继承 List<T> 来实现 collections 是个坏主意?

If you want to get something like this functionality, consider making a constructor argument:如果您想获得类似的功能,请考虑使用构造函数参数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM