3

NullReferenceException我在以下代码中遇到运行时异常:

public class Container
{
    public IList<string> Items { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var container = new Container() { Items = {"Test"} };
    }
}

编译器无法创建接口实例是合乎逻辑的,但我遇到了运行时异常,而不是编译时间。当我进一步调查这种行为时,我更加困惑:

    var container = new Container() { Items = {} }; //Legal, Items is null after initialization

    var container = new Container() { Items = { "Test" } }; //Legal, throws exception
    container.Items = {}; //Illegal doesn't compile
    container.Items = {"Test"}; //Illegal doesn't compile

这是某种错误还是我不明白?我正在使用.net framework 4.0

4

2 回答 2

3

它编译,因为编译器不知道是否List已经在其他地方初始化。您可以通过在构造函数中添加初始化来使其工作:

public class Container
{
    public IList<string> Items { get; set; }

    public Container()
    {
        Items = new List<string>();
    }
}

或者更改属性以隐藏字段,该字段在创建类实例时初始化:

private IList<string> items = new List<string>();
public IList<string> Items
{
    get { return items; }
    set { items = value; }
}

然后,var container = new Container() { Items = { "Test" } };工作得很好。

在运行时.Add()为集合初始化程序组中的每个项目调用方法。当属性未初始化时,new List<string>它具有null值,这NullReferenceException就是抛出的原因。

对象和集合初始化器(C# 编程指南)

通过使用集合初始化器,您不必在源代码中指定对类的 Add 方法的多次调用;编译器添加调用

于 2013-03-20T09:59:22.987 回答
0

你没有初始化List

  var container = new Container() { Items = new List<string>() { "Test" } };

顺便说一句,对于编译器来说,以下是合法的,它没有任何问题(语法正确等)

var container = new Container() { Items = {} }; 

但是因为编译器不知道Itemslist 没有被初始化(你没有在集合初始化器中传递任何项目{})该.Add方法不会被调用List并且运行时不会知道该Items对象是 null

另一方面,以下对于编译器是合法的,但它在运行时引发异常,因为您尝试初始化传递项目的列表(由于上述相同的原因,它对编译器是正确的)所以当运行时将调用后台的方法,由于没有初始化.Add,会抛出空引用异常Items

 var container = new Container() { Items = { "Test" } }; 
于 2013-03-20T09:55:42.450 回答