简体   繁体   English

为什么这个嵌套对象初始化器抛出一个空引用异常?

[英]Why does this nested object initializer throw a null reference exception?

The following testcase throws a null-reference exception, when it tries to assign Id to an object which is null, since the code is missing the "new R" before the object initializer. 以下测试用例在尝试将Id分配给空的对象时抛出空引用异常,因为代码在对象初始值设定项之前缺少“new R”。

Why is this not caught by the compiler? 为什么这不会被编译器捕获? Why is it allowed, in which use-cases would this be a meaningful construct? 为什么允许这样,用例会是一个有意义的构造?

[TestClass]
public class ThrowAway
{
    public class H
    {
        public int Id { get; set; }
    }

    public class R
    {
        public H Header { get; set; }
    }

    [TestMethod]
    public void ThrowsException()
    {
        var request = new R
                      {
                          Header =
                          {
                              Id = 1
                          },
                      };
    }
}

The compiler doesn't give a warning because you could have: 编译器不会发出警告,因为您可以:

public class R
{
    public H Header { get; set; }

    public R()
    {
        Header = new H();
    }
}

so Header could be initialized by someone/something. 所以Header可以由某人/某事初始化。 Solving if someone/something will initialize Header is a complex problem (probably similar to the Halting problem)... Not something that a compiler wants to solve for you :-) 解决是否某人/某事将初始化Header是一个复杂的问题(可能类似于Halting问题)...不是编译器想要为你解决的问题:-)

From the C# specifications: 从C#规范:

A member initializer that specifies an object initializer after the equals sign is a nested object initializer, ie an initialization of an embedded object. 在等号后面指定对象初始值设定项的成员初始值设定项是嵌套对象初始值设定项,即嵌入对象的初始化。 Instead of assigning a new value to the field or property, the assignments in the nested object initializer are treated as assignments to members of the field or property . 而不是为字段或属性分配新值,嵌套对象初始值设定项中的赋值被视为对字段或属性成员的赋值 Nested object initializers cannot be applied to properties with a value type, or to read-only fields with a value type. 嵌套对象初始值设定项不能应用于具有值类型的属性,也不能应用于具有值类型的只读字段。

We are in the case of nested initializer, and see the bolded part. 我们是嵌套初始化器的情况,并看到粗体部分。 I didn't know it. 我不知道。

Now, note that new R { } is, by C# spec, an 7.6.10.1 Object creation expressions followed by an object-initializer , while the Header = { } is a "pure" 7.6.10.2 Object initializers . 现在,请注意,根据C#规范, new R { }7.6.10.1 Object creation expressions后跟object-initializer ,而Header = { }是“纯” 7.6.10.2 Object initializers

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

相关问题 为什么会话对象抛出空引用异常? - Why does session object throw a null reference exception? 为什么这会引发空引用异常? - Why does this throw a null reference exception? 为什么Silverlight View不会引发null异常? - Why does Silverlight View not throw a null exception? 为什么 HttpRequestMessage.Content.Headers.ContentType 会抛出 null 引用异常? - Why does HttpRequestMessage.Content.Headers.ContentType throw null reference exception? 什么时候遍历列表会引发Null Reference Exception? - When does looping through a list throw a Null Reference Exception? 使用对象初始化程序引发新异常 - Throw new exception using object initializer 为什么会抛出异常 - Why does this throw exception 如果Any()为true,为什么LINQ在Count()上抛出空引用错误? - Why does LINQ throw a null reference error on Count() if Any() is true? 为什么MVC在似乎没有Null引用时会抛出NullReferenceException? - Why does MVC throw a NullReferenceException when there seems to be no Null Reference? 为什么 AWS Lambda 环境中的 EPPlus Excel 库会抛出“'Gdip' 的类型初始值设定项引发异常” - Why Does EPPlus Excel Library in AWS Lambda Environment Throw "The type initializer for 'Gdip' threw an exception"
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM