15 回答

TA貢獻1821條經驗 獲得超5個贊
這意味著有問題的變量沒有任何意義。我可以這樣生成:
SqlConnection connection = null;connection.Open();
這將拋出錯誤,因為當我聲明變量“ connection
”時,它沒有指向任何東西。當我嘗試調用成員“ Open
”時,沒有引用它來解決它,它將拋出錯誤。
要避免此錯誤:
在嘗試對它們執行任何操作之前始終初始化對象。
如果您不確定對象是否為null,請檢查它
object == null
。
JetBrains的Resharper工具將識別代碼中可能存在空引用錯誤的每個位置,允許您進行空檢查。這個錯誤是錯誤的頭號來源,恕我直言。

TA貢獻1824條經驗 獲得超8個贊
請注意,無論情況如何,.NET中的原因始終相同:
您正在嘗試使用值為
Nothing
/ 的引用變量null
。當值為Nothing
/null
為引用變量時,這意味著它實際上并未持有對堆上存在的任何對象的實例的引用。您從未向變量分配內容,從未創建分配給變量的值的實例,或者您將變量設置為
Nothing
/null
manual,或者您調用了將變量設置為Nothing
/ 的函數null
。

TA貢獻1851條經驗 獲得超4個贊
您正在使用包含空值引用的對象。所以它給出了一個null異常。在示例中,字符串值為null,并且在檢查其長度時,發生了異常。
例:
string value = null;if (value.Length == 0) // <-- Causes exception{ Console.WriteLine(value); // <-- Never reached}
異常錯誤是:
未處理的異常:
System.NullReferenceException:未將對象引用設置為對象的實例。在Program.Main()

TA貢獻1815條經驗 獲得超10個贊
object o = null;DateTime d = (DateTime)o; // NullReferenceException
其中一個開箱轉換(CAST)從 object
(或從其中一個類System.ValueType
或System.Enum
,或從一個接口類型)到一個值類型(比其它Nullable<>
本身)給出NullReferenceException
。
在另一個方向上,一拳擊轉換從一個Nullable<>
具有HasValue
等于false
以引用類型,可以給一個null
參考其然后可以在以后導致NullReferenceException
。經典的例子是:
DateTime? d = null;var s = d.ToString(); // OK, no exception (no boxing), returns ""var t = d.GetType(); // Bang! d is boxed, NullReferenceException
有時拳擊以另一種方式發生。例如,使用這種非泛型擴展方法:
public static void MyExtension(this object x){ x.ToString();}
以下代碼將有問題:
DateTime? d = null;d.MyExtension(); // Leads to boxing, NullReferenceException occurs inside the body of the called method, not here.
出現這些情況是因為運行時在裝箱Nullable<>
實例時使用的特殊規則。

TA貢獻1803條經驗 獲得超6個贊
我對回答這個問題有不同的看法。這種答案“我還能做些什么來避免它? ”
當跨不同層工作時,例如在MVC應用程序中,控制器需要服務來調用業務操作。在這種情況下,可以使用Dependency Injection Container初始化服務以避免NullReferenceException。這意味著您不必擔心檢查null并且只需從控制器調用服務,就好像它們總是可用(并初始化)為單例或原型。
public class MyController{ private ServiceA serviceA; private ServiceB serviceB; public MyController(ServiceA serviceA, ServiceB serviceB) { this.serviceA = serviceA; this.serviceB = serviceB; } public void MyMethod() { // We don't need to check null because the dependency injection container // injects it, provided you took care of bootstrapping it. var someObject = serviceA.DoThis(); }}

TA貢獻1836條經驗 獲得超3個贊
關于“我該怎么辦”,可以有很多答案。
在開發過程中防止此類錯誤情況的更“正式”方法是在代碼中按合同設計。這意味著您需要在開發時在系統上設置類不變量,和/或甚至函數/方法前置條件和后置條件。
簡而言之,類不變量確保您的類中存在一些在正常使用中不會被違反的約束(因此,類不會處于不一致狀態)。前提條件意味著作為函數/方法的輸入給出的數據必須遵循一些約束集并且永遠不違反它們,并且后置條件意味著函數/方法輸出必須再次遵循設置約束而不違反它們。在執行無錯誤程序期間永遠不應違反合同條件,因此在調試模式下實際檢查合同設計,同時在發布中禁用合同條件,以最大化已開發的系統性能。
這樣,您可以避免NullReferenceException
違反約束集的情況。例如,如果X
在類中使用對象屬性,稍后嘗試調用其中一個方法并且X
具有空值,則會導致NullReferenceException
:
public X { get; set; }public void InvokeX(){ X.DoSomething(); // if X value is null, you will get a NullReferenceException}
但是如果你設置“屬性X必須永遠不會有空值”作為方法前置條件,那么你可以阻止前面描述的場景:
//Using code contracts:[ContractInvariantMethod]protected void ObjectInvariant () { Contract.Invariant ( X != null ); //...}
出于這個原因,.NET應用程序存在Code Contracts項目。
或者,可以使用斷言來應用合同設計。
更新:值得一提的是,這個術語是Bertrand Meyer 在設計Eiffel編程語言時創造的。
- 15 回答
- 0 關注
- 9943 瀏覽
添加回答
舉報