简体   繁体   English

为什么在对象初始值设定项中允许没有“new”的集合初始值设定项但不允许在外部?

[英]Why is a collection initializer without `new` allowed inside an object initializer but not outside?

I noticed strange behaviour when initializing collection property.我在初始化集合属性时注意到了奇怪的行为。

Consider:考虑:

class X
{
    public IList<int> Ints { get; set; }
}

I can initialize Ints like that:我可以像这样初始化Ints

var theObject = new X
{
    Ints = { 12, 3, 4, 5, 6 }
};

But I cannot do that:但我不能这样做:

var x = new X();

x.Ints = { 12, 3, 4, 5, 6 }

Any ideas why?任何想法为什么? It seems pretty unintuitive.这似乎很不直观。

new X ... is the start of an object creation expression . new X ...对象创建表达式的开始。 In this kind of expressions, an object or collection initializer is allowed:在这种表达式中,允许使用对象或集合初始值设定项:

object_creation_expression
    : 'new' type '(' argument_list? ')' object_or_collection_initializer?
    | 'new' type object_or_collection_initializer  // <--- here!
    ;

object_or_collection_initializer
    : object_initializer
    | collection_initializer
    ;

In your code, you have an object initialiser { Ints = ... } .在您的代码中,您有一个对象初始值设定项{ Ints = ... } Inside that, there is another collection initialiser { 12, 3, 4, 5, 6 } .在里面,还有另一个集合初始化器{ 12, 3, 4, 5, 6 } This is allowed, as per the grammar:根据语法,这是允许的:

object_initializer
    : '{' member_initializer_list? '}'
    | '{' member_initializer_list ',' '}'
    ;

member_initializer_list
    : member_initializer (',' member_initializer)*
    ;

member_initializer
    : initializer_target '=' initializer_value
    ;

initializer_target
    : identifier
    | '[' argument_list ']'
    ;

initializer_value
    : expression
    | object_or_collection_initializer // <---- here!
    ;

An initializer_value can either be an expression, or another object_or_collection_initializer .一个initializer_value可以是一个表达式,也可以是另一个object_or_collection_initializer This also implies that, though they may look like it, object_or_collection_initializer , ie things like { 12, 3, 4, 5, 6 } , are not a kind of expression.这也意味着,尽管它们看起来很像,但object_or_collection_initializer ,即{ 12, 3, 4, 5, 6 } ,并不是一种表达式。

On the other hand, assignments don't allow this.另一方面, 作业不允许这样做。 Assignments only allow an expression to be on the right hand side:赋值只允许表达式位于右侧:

assignment
    : unary_expression assignment_operator expression
    ;

As pointed out in the comments, this is an example of a collection initializer.正如评论中所指出的,这是一个集合初始值设定项的示例。

It's really syntactic sugar for something along the lines of the following:它实际上是以下内容的语法糖:

var theObject = new X();
theObject.Items.Add(12);
theObject.Items.Add(3);
theObject.Items.Add(4);
theObject.Items.Add(5);
theObject.Items.Add(6);

Anything that fits the right 'shape' can be initialized this way.任何适合正确“形状”的东西都可以通过这种方式进行初始化。 (Essentialy it's looking for an Add(...) method matching the right signature of your types.) You can even use this to initialize Dictionary collections. (本质上,它正在寻找与您的类型的正确签名匹配的Add(...)方法。)您甚至可以使用它来初始化 Dictionary 集合。

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

相关问题 对象初始化,为什么要调用集合初始化 - object initialization, why collection initializer is being called 可以混合对象初始化器和集合初始化器吗? - Possible to mix object initializer and collection initializer? 在对象初始值设定项中使用“ this” - Using “this” inside an object initializer 在对象初始值设定项中的嵌入集合上使用集合初始值设定项时没有警告 - No warning when using a Collection Initializer on an embedded collection in an Object Initializer 为什么我可以使用具有只读自动属性的匿名集合初始化程序,而我不能使用 object 初始化程序 - Why can I use an anonymous collection initializer with a read-only auto-property while I can't use an object initializer 对象初始化器 - object initializer 在集合/对象初始化程序中使用Random.Next() - Using Random.Next() in a collection/object initializer 为什么显然由List &lt;&gt;的集合初始值设定项克隆对象? - Why are objects apparently cloned by collection initializer for List<>?> 无法理解为什么无法初始化对象初始化程序中的数组初始化程序 - Can't understand why array initializer in object initializer cannot compiled 组合列表初始化器和 object 初始化器 - Combining List initializer and object initializer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM