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

c# – 在对象初始值设定项中使用数组初始值设定项时的NRE

参见英文答案 > Empty collection initializer for list property results in null                                    1个
在以下情况中使用数组初始值设定项时,我观察到一些奇怪的行为(在VS2013中测试过):

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

    void Main(string[] args)
    {
        // (1) it compiles,but failing with NRE in runtime
        var a = new A { Items = { 1,2,3 } };

        // (2) it does not compile,as expected
        List<int> b = { 1,3 };
    }

实际上我会期望在情况(1)中出现编译器错误,与我在情况(2)中的情况相同:只能使用数组初始化表达式来分配给数组类型.请尝试使用新表达式.但是case(1)编译时没有任何问题,并且在运行时可以预期NullReferenceException失败.有人可以解释为什么编译器允许这种情况(1)?

解决方法

以下是C#规范的相关引用(第5版,第7.6.10.2节):

A member initializer that specifies a collection initializer after the equals sign is an initialization of an embedded collection. Instead of assigning a new collection to the field or property,the elements given in the initializer are added to the collection referenced by the field or property. The field or property must be of a collection type that satisfies the requirements specified in §7.6.10.3.

因为你在对象初始化器中使用了一个集合初始化器,行为是不同的,这段代码

var a = new A { Items = { 1,3 } };

编译成这样的东西(你可以通过查看IL来验证这一点):

var a = new A();
a.Items.Add(1);
a.Items.Add(2);
a.Items.Add(3);

这当然会抛出NullReferenceException,因为Items为null.

您可以通过向A类添加构造函数来修复崩溃:

class A
{
    public List<int> Items { get; set; }
    public A() { Items = new List<int>(); }
}

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

相关推荐