繁体   English   中英

这两个集合初始化表达式的变化有什么区别?

[英]What is the difference between these two variations of collection initialiser expressions?

我一直在使用C#,但最近注意到我的一个单元测试的行为根据我使用的集合初始化表达式的变化而改变:

  • var object = new Class { SomeCollection = new List<int> { 1, 2, 3 } };
  • var object = new Class { SomeCollection = { 1, 2, 3 } };

直到这一点,我认为第二种形式只是语法糖,在语义上等同于第一种形式。 然而,在这两种形式之间切换导致我的单元测试失败。

下面的示例代码演示了这一点:

void Main()
{
    var foo1 = new Foo { Items = new List<int> { 1, 2, 3} };
    var foo2 = new Foo { Items = { 1, 2, 3 } };

    foo1.Dump();
    foo2.Dump();
}

class Foo
{
    public List<int> Items { get; set; }
}

当我运行它时,第一个赋值工作正常但第二个赋值为NullReferenceException

我的直觉是,在幕后,编译器将这两个表达式视为:

var foo1 = new Foo();
foo1.Items = new List<int> { 1, 2, 3 }; 

var foo2 = new Foo();
foo2.Items.Add(1);
foo2.Items.Add(2);
foo2.Items.Add(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;

与之相比:

var foo = new Foo
{
    Collection = new List<int> { 1 },
    Property = new Bar { 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 };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM