[英]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.