1

初始化集合属性时我注意到奇怪的行为。

考虑:

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 }

任何想法为什么?这似乎很不直观。

4

2 回答 2

5

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

Aninitializer_value可以是一个表达式,也可以是另一个object_or_collection_initializer。这也意味着,虽然它们可能看起来像object_or_collection_initializer{ 12, 3, 4, 5, 6 }但也不是一种表达方式。

另一方面,作业不允许这样做。赋值只允许表达式位于右侧:

assignment
    : unary_expression assignment_operator expression
    ;
于 2020-10-28T01:39:02.997 回答
0

正如评论中所指出的,这是集合初始化程序的一个示例。

它实际上是以下内容的语法糖:

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 集合。

于 2020-10-28T01:41:00.557 回答