C# 集合初始值设定项表达式的这两种变体之间有什么区别?
我使用C#已经有一段时间了,但最近注意到,我的一个单元测试的行为根据我使用的集合初始化器表达式的变化而变化:C# 集合初始值设定项表达式的这两种变体之间有什么区别?,c#,collection-initializer,C#,Collection Initializer,我使用C#已经有一段时间了,但最近注意到,我的一个单元测试的行为根据我使用的集合初始化器表达式的变化而变化: var object=newclass{SomeCollection=newlist{1,2,3} var object=newclass{SomeCollection={1,2,3} 在此之前,我一直认为第二种形式只是语法上的糖分,在语义上与第一种形式等价。然而,在这两种形式之间的切换导致我未能通过单元测试 下面的示例代码演示了这一点: void Main() { var foo1
var object=newclass{SomeCollection=newlist{1,2,3}代码>
var object=newclass{SomeCollection={1,2,3}代码>
void Main()
{
var foo1=新Foo{Items=新列表{1,2,3};
var foo2=新Foo{Items={1,2,3};
foo1.Dump();
foo2.Dump();
}
福班
{
公共列表项{get;set;}
}
当我运行此操作时,第一个赋值工作正常,但第二个赋值会导致NullReferenceException
我的直觉是,在幕后,编译器将这两个表达式视为:
var foo1=new Foo();
foo1.Items=新列表{1,2,3};
var foo2=新的Foo();
foo2.项目。添加(1);
foo2.项目。添加(2);
foo2.项目。添加(3);
这个假设准确吗?是的,你的假设准确。如果对象初始值设定项只有:
{
Property = { ... }
}
而不是
{
Property = expression
}
然后不使用属性的setter-使用getter,然后调用Add
方法,或者在返回值中设置属性。因此:
var foo = new Foo
{
Collection = { 1 }
Property =
{
Value = 1
}
};
相当于:
// Only the *getters* for Collection and Property are called
var foo = new Foo();
foo.Collection.Add(1);
foo.Property.Value = 1;
// The setters for Collection and Property are called
var foo = new Foo();
foo.Collection = new List<int> { 1 };
foo.Property = new Bar { Value = 1 };
与之相比:
var foo = new Foo
{
Collection = new List<int> { 1 },
Property = new Bar { Value = 1 }
};
var foo=新foo
{
集合=新列表{1},
属性=新条{Value=1}
};
这相当于:
// Only the *getters* for Collection and Property are called
var foo = new Foo();
foo.Collection.Add(1);
foo.Property.Value = 1;
// The setters for Collection and Property are called
var foo = new Foo();
foo.Collection = new List<int> { 1 };
foo.Property = new Bar { Value = 1 };
//调用集合和属性的setter
var foo=new foo();
foo.Collection=新列表{1};
foo.Property=newbar{Value=1};
这将对您有所帮助:是否应该将等效项也添加到新集合中,或者只是添加?