簡體   English   中英

對象初始化期間的 NullReferenceException

[英]NullReferenceException during object initialization

為什么在下面的代碼中嘗試設置 X 的值時會出現 NullReferenceException? 當我在初始化B時使用new關鍵字時它工作正常,但是為什么它在沒有new情況下編譯良好,然后在運行時失敗?

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
                }
            };
    }
}

初始化語法可能很棘手。 在您的代碼中,您嘗試設置aBX的值而不先設置B的值。 您的代碼轉換為:

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

...這會產生與您現在相同的異常。 那是因為aB被初始化為null除非你明確地為它創建一個實例。

正如您所指出的,這將起作用:

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

您還可以確保A的構造函數初始化B

    public _B B = new A._B();

為什么它在沒有 new 的情況下編譯良好,然后在運行時失敗?

編譯器需要做太多的工作來挖掘A類的代碼並意識到此時B肯定會為空:正如我指出的那樣,您可以更改A的構造函數的實現以確保這是不是這樣。 這就是空引用異常是最常見的異常類型的原因之一。

避免這種情況的最佳策略是在構造函數中將所有字段初始化為非空值。 如果在調用構造函數之前您不知道要賦予它們什么值,那么讓構造函數將這些值作為參數。 如果您希望您的某個字段可能並不總是有值,您可以使用像我的Maybe<>結構這樣的可選類型來強制程序員在編譯時處理這個事實。

2021 年更新

現在 C# 支持可為空的引用類型,您可以使用它來鼓勵/強制程序員知道您的字段可能為空,如果這是您想要采取的路線。

    public _B? B;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM