2016-10-20 43 views
0

为什么下面的代码会编译,但会抛出NullReferenceException?列表中的空例外<T>初始化

using System.Collections.Generic; 

class Program 
{ 
    static void Main() 
    { 
     C c = new C { P = { "" } }; 
    } 
} 

class C 
{ 
    public List<string> P; 
} 
+1

因为'C'中的'P'为空,所以你试图赋给'P = {“”}' – Liam

+1

因为P的状态直到运行时才知道。您可以拥有实例化对象的代码。从编译器的角度来看,它检查对象是否正确,而不是它存在。编译器无法遍历整个代码库中的每个逻辑树 – Liam

+0

@juharr编译器如何知道(一般情况下)C的构造函数是否将“P”设置为任何值? – hvd

回答

1

基本上代码

C c = new C { P = { "" } }; 

C temp = new C(); 
temp.P.Add(""); 
C c = temp; 

,所以它不是创建列表,只是想添加到它,因此运行时错误真的很短的手,但没有编译错误。

+0

使用系统; using System.Collections.Generic; public class Program { public static void Main(string [] args) {c} = new C {P = {“b”}}; Console.WriteLine(c.P.Count); } } class C { public list P {get;私人设置; } public C() P = new List {“a”}; } } –

+0

在我看来,语法糖太混乱了。如果你写'C c = new C {P = new List {“”}};'一切都很好,因为现在最后一个'='意味着分配给'P'(___write___),这当然是好的。在原始示例中,'='表示___读取'P'的值并尝试调用'P'的编译时类型上存在的'Add'方法。 –

+0

@CsuporJenő问题是关于它编译的原因,但导致一个异常,而不是如何解决它,使其不会引起异常。 – juharr

0

其符合的原因是因为

C c = new C { P = { "" } }; 

是有效的C#。

它只在运行时检查P是否为空 - 因此运行时为NullReferenceException。

+2

严重的是,重新打开和回答明显的重复? – hvd

+1

@ hvd - 我不认为这是一个明显的重复。但是,我看到我被推翻了。不幸的是,我没有看到运行时参考被埋没在许多问题的答案中。 – ChrisF

+0

我会说它是由'Book b1 = new Book {Author = {Age = 45}}';'部分答案在“间接”标题下。如果你能解释为什么你觉得它没有被覆盖,我会很乐意尝试编辑其他的答案,使其更清晰。我希望你至少同意*应该*通过规范问题和答案来回答。这就是我们拥有它们的原因。 – hvd