簡體   English   中英

為什么在對象初始值設定項中允許沒有“new”的集合初始值設定項但不允許在外部?

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

我在初始化集合屬性時注意到了奇怪的行為。

考慮:

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

我可以像這樣初始化Ints

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

但我不能這樣做:

var x = new X();

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

任何想法為什么? 這似乎很不直觀。

new X ...對象創建表達式的開始。 在這種表達式中,允許使用對象或集合初始值設定項:

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
    ;

在您的代碼中,您有一個對象初始值設定項{ Ints = ... } 在里面,還有另一個集合初始化器{ 12, 3, 4, 5, 6 } 根據語法,這是允許的:

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

一個initializer_value可以是一個表達式,也可以是另一個object_or_collection_initializer 這也意味着,盡管它們看起來很像,但object_or_collection_initializer ,即{ 12, 3, 4, 5, 6 } ,並不是一種表達式。

另一方面, 作業不允許這樣做。 賦值只允許表達式位於右側:

assignment
    : unary_expression assignment_operator expression
    ;

正如評論中所指出的,這是一個集合初始值設定項的示例。

它實際上是以下內容的語法糖:

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

任何適合正確“形狀”的東西都可以通過這種方式進行初始化。 (本質上,它正在尋找與您的類型的正確簽名匹配的Add(...)方法。)您甚至可以使用它來初始化 Dictionary 集合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM