问题描述
初始化集合属性时,我发现奇怪的行为。
考虑:
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集合。