微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么在对象初始值设定项中允许而不使用“ new”的集合初始值设定项?

如何解决为什么在对象初始值设定项中允许而不使用“ new”的集合初始值设定项?

初始化集合属性时,我发现奇怪的行为。

考虑:

from os import path
if path.exists(f"C:/<your folders>/Payments - {date}.xlsx"):
    print("Found")
else:
    print("Not found")

我可以这样初始化class X { public IList<int> Ints { get; set; } }

Ints

但是我不能这样做:

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

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

解决方法

new X ...object creation expression的开始。在这种类型的表达式中,允许使用对象或集合初始化程序:

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
    ;

在您的代码中,您有一个object initialiser { Ints = ... }。在其中,还有另一个collection initialiser { 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,6 }之类的东西,但不是一种表达方式。

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。