C# 初始化类上的集合成员
我有一个具有集合属性的类:C# 初始化类上的集合成员,c#,collection-initializer,C#,Collection Initializer,我有一个具有集合属性的类: class MyClass { public MyCollection Coll { get; private set; } public MyClass() { this.Coll = new MyCollection(); } } class MyCollection : IList { ... } 现在,我正在创建我的类的两个不同实例: var o1 = new MyClass() { Coll = {"1", "2"}}; var o2 =
class MyClass
{
public MyCollection Coll { get; private set; }
public MyClass() { this.Coll = new MyCollection(); }
}
class MyCollection : IList { ... }
现在,我正在创建我的类的两个不同实例:
var o1 = new MyClass() { Coll = {"1", "2"}};
var o2 = new MyClass() { Coll = new MyCollection() {"1", "2"} };
我知道编译器抱怨后者,因为属性的setter不存在(或者在本例中不可公开访问)。然而,第一个也是赋值-尽管是集合初始值设定项
我假设集合初始值设定项只允许get-only属性,因为它们只是在IList
上调用Add
,而实际上并不调用属性的getter。是这样吗?从您的问题:
我假设集合初始值设定项[…]只是在IList
[…]上调用Add
这个假设是正确的。集合初始值设定项是语法糖,C#编译器在编译过程中将其转换为更明确的内容。例如,以下行:
var l = new List<int>() { 1, 2 };
我们可以再次检查MSIL以验证这一点:
newobj MyClass..ctor
stloc.1 // Store MyClass instance at local variable "1".
ldloc.1 // Load MyClass instance onto stack.
callvirt MyClass.get_Coll // Call getter of "Coll" and push the MyCollection
// instance onto the stack.
ldstr "1" // Push the string "1" onto the stack...
callvirt MyCollection.Add // ...and call "Add".
pop // Discard the return value of "Add".
ldloc.1
callvirt MyClass.get_Coll
ldstr "2"
callvirt MyCollection.Add
pop
o1
是否运行,或者在对null
对象调用Add
时是否看到运行时错误?虽然标记为重复,但投票给一个更简洁的对象。答案很好,我已经说到点子上了。@Abbondanza,你的答案很好,但Jon Skeet中的样本可能更容易吸收。我建议在您的答案中添加Jon的代码示例,以用简洁的代码完整地回答这个简洁的问题example@DmitryEgorov,说得好。我扩展了答案。
newobj List<System.Int32>..ctor // Create list object.
stloc.0 // Store list object as local variable "0".
ldloc.0 // Push local variable "0" onto the stack.
ldc.i4.1 // Push 4-byte integer constant "1" onto the stack.
callvirt List<System.Int32>.Add // Call "Add" (uses and pops the last two values from
// the stack).
ldloc.0 // Push list onto stack again.
ldc.i4.2 // Push constant "2" onto stack.
callvirt List<System.Int32>.Add // Call "Add" again.
var o1 = new MyClass();
o1.Coll.Add("1");
o1.Coll.Add("2");
newobj MyClass..ctor
stloc.1 // Store MyClass instance at local variable "1".
ldloc.1 // Load MyClass instance onto stack.
callvirt MyClass.get_Coll // Call getter of "Coll" and push the MyCollection
// instance onto the stack.
ldstr "1" // Push the string "1" onto the stack...
callvirt MyCollection.Add // ...and call "Add".
pop // Discard the return value of "Add".
ldloc.1
callvirt MyClass.get_Coll
ldstr "2"
callvirt MyCollection.Add
pop