[英]NullReferenceException in C# when the container is initialized
在下面列出的C#代碼中,出現錯誤“ NullReferenceException”:
“你調用的對象是空的”
我猜該錯誤與繼承和/或模板定義有關。 該列表已初始化,在調試時,我可以確認該列表未指向NULL。 我不知道該怎么做。 (對不起的類名/結構很抱歉)。 例外發生在這里:this.localSMT.doSomething(base.list);
public class VTEST<V>
{
public List<V> list;
public LocalSMT<V> localSMT;
public VTEST()
{
list = new List<V>();
}
}
public class VTEST_FSUB<V> : VTEST<V>
{
public VTEST_FSUB()
{
do_virtual();
}
public void do_virtual()
{
this.localSMT.doSomething(base.list);
}
}
public class VTEST_RUN : VTEST_FSUB<int>
{
public VTEST_RUN()
{
localSMT = new VTEST_SUB();
}
}
public class LocalSMT<V>
{
public LocalSMT() { }
public virtual void doSomething(List<V> value) { }
}
public class VTEST_SUB : LocalSMT<int>
{
public VTEST_SUB(){}
public override void doSomething(List<int> value) {
System.Console.WriteLine("VTEST_SUB VIRTUAL");
}
}
class Program
{
Program() {}
static void Main(string[] args)
{
VTEST_RUN run = new VTEST_RUN();
}
}
問題在於, VTEST_FSUB<V>
構造函數主體在VTEST_RUN
構造函數主體之前執行。 所以,當do_virtual
被調用時, localSMT
仍然是空。 然后do_virtual
嘗試在localSMT
上調用方法,因此是異常。
基本上,層次結構中任何類的初始化順序為:
有關更多詳細信息,請參見我有關構造函數鏈接的文章 。
經驗教訓:
readonly
字段:如果您將值沿構造函數鏈傳遞並在VTEST<V>
構造函數中進行設置,則不會有問題。 (由於下一點, readonly
字段仍然很readonly
...) do_virtual
在VTEST_FSUB<V>
是抽象的,並且可以重寫以在VTEST_RUN
調用localSMT.doSomething
,則很容易遇到相同的問題。 它在構造函數主體運行之前仍會執行,這令人驚訝。 您在構造函數中調用的所有內容都在部分初始化的對象上進行操作,這是一個不穩定的情況。 嘗試:
public void do_virtual()
{
localSMT=new LocalSMT<V>();
localSMT.doSomething(list);
}
在public class VTEST_FSUB<V> : VTEST<V>
在使用之前,您沒有實例化localSMT,所以它不起作用。
編輯:或
public class VTEST<V>
{
public List<V> list;
public LocalSMT<V> localSMT;
public VTEST()
{
list = new List<V>();
localSMT = new LocalSMT<V>();
}
}
最好在構造函數中對其進行初始化。
第二個解決方案是更清潔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.