对象初始化期间发生NullReferenceException [英] NullReferenceException during object initialization

查看:63
本文介绍了对象初始化期间发生NullReferenceException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么在下面的代码中尝试设置X的值时会出现NullReferenceException?当我在初始化 B 时使用 new 关键字时,它可以很好地工作,但是为什么在没有 new 的情况下,它可以很好地编译,然后在运行时失败呢?

Why there's a NullReferenceException when trying to set value of X in the code below? It works fine when I use new keyword when initializing B, but why it compiles fine without new and then fails during runtime?

https://dotnetfiddle.net/YNvPog

public class A
{
    public _B B;
    public class _B
    {
        public int X;
    }
}

public class Program
{
    public static void Main()
    {
        var a=new A{
                B={
                    X=1
                }
            };
    }
}

推荐答案

初始化语法可能很棘手.在您的代码中,您尝试设置 a.B.X 的值,而不先设置 B 的值.您的代码将转换为:

Initialization syntax can be tricky. In your code, you're trying to set the value of a.B.X without first setting the value of B. Your code translates to:

var a = new A();
a.B.X = 1;

...将产生与您现在得到的异常相同的异常.这是因为 a.B 被初始化为 null ,除非您明确为其创建实例.

... which would produce the same exception you're getting now. That's because a.B is initialized to null unless you explicitly create an instance for it.

如您所述,这将起作用:

As you noted, this will work:

    var a=new A{
            B= new _B {
                X=1
            }
        };

您还可以确保 A 的构造函数初始化 B .

You could also make sure that A's constructor initializes a B.

    public _B B = new A._B();

为什么没有新程序就可以正常编译,然后在运行时失败?

why it compiles fine without new and then fails during runtime?

对于编译器来说,要深入研究 A 类的代码并意识到 B 在此时肯定为空,将需要大量的工作:我指出您可以更改 A 的构造函数的实现,以确保不是这种情况.这是空引用异常是最常见的异常类型之一.

It would require too much work for the compiler to dig into the code for your A class and realize that B will definitely be null at this point in time: as I pointed out you could change the implementation of A's constructor to make sure that's not the case. This is one reason that null reference exceptions are the most common type of exception out there.

避免这种情况的最佳策略是在构造函数中将所有字段初始化为非null值.如果在调用构造函数之前不知道要给它们提供什么值,请使构造函数将这些值用作参数.如果您希望某个字段可能并不总是具有值,则可以使用可选类型像我的 Maybe<> 结构强制程序员在编译时处理该事实.

The best strategy to avoid this is to initialize all of your fields to non-null values in the constructor. If you won't know what value to give them until your constructor is invoked, then make your constructor take those values as parameters. If you expect one of your fields may not always have a value, you can use an optional type like my Maybe<> struct to force programmers to deal with that fact at compile-time.

现在C#支持可引用类型,可以用来鼓励/强迫程序员知道您的字段可以为空,如果那是您要采用的方法.

Now C# supports nullable reference types, which you can use to encourage/force programmers to know that your field could be null, if that's the route you want to take.

    public _B? B;

这篇关于对象初始化期间发生NullReferenceException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆