2016-09-15 50 views
2

我在讀this post回答者提到他首選ArgumentNullException而不是NullReferenceExceptionNullReferenceException vs ArgumentNullException

MSDN提到,對於NullReferenceException

時,有一個嘗試取消引用空對象引用時引發的異常。

ArgumentNullExceptionthey說:

當空引用(在Visual Basic中爲Nothing)傳遞給不接受它作爲有效參數的方法時引發的異常。

回答者似乎說你可以使用。

是否有任何理由或任何情況下,我應該選擇一個在另一個?

附:

我知道這個問題可能是基於意見的。 我想要事實,背景和情況。我對個人偏好不感興趣。

+1

*我應該選擇一個在另一個*你是指你應該拋出哪個,或者你應該發生什麼? – DaveShaw

+1

非常類似的問題http://stackoverflow.com/questions/463302/argumentnullexception-or-ullullferenceexception-from-extension-method其答案與這個問題有關。 – hatchet

+1

你也不能使用。 NRE必須保留給*實際*因解除引用而死的程序。您可以使用ArgumentNullException來*防止它們在NRE上摔倒。告訴客戶程序員「我知道你做錯了,請不要傳null」。 NRE不會發送這樣精美的消息,當它被拋出時,你不能確定它是你的錯誤還是圖書館的錯誤。 –

回答

10

如果您明確地在您的代碼中拋出異常,應該選擇ArgumentNullException

NullReferenceException當空引用/指針被解除引用被自動由CLR拋出:

unsafe 
{ 
    int* ptr = (int*)0; // Casting 0 to pointer is null reference. 
    int val = *ptr; // NullReferenceException thrown. 
} 

這最常發生在方法或屬性上調用空引用:

string s = null; 
string substring = s.Substring(0, 2); // NullReferenceException thrown. 

在大多數情況下,NullReferenceException不應該顯式拋出代碼。

ArgumentNullException用於檢查空引用作爲參數傳遞的情況,通常用於防止NullReferenceException

static string firstTwo(string s) 
{ 
    if (s == null) 
    { 
     throw new ArgumentNullException("s"); 
    } 
    return s.Substring(0, 2); // without the original check, this line would throw a NullReferenceException if s were null. 
} 

此檢查的目的是清楚地讓調用者知道null是否被傳遞,null是不允許的。否則,如果你只是讓NullReferenceException被拋出,調用者只看到

對象引用不設置到對象

的一個實例,這是不是因爲這是有意義的(使用支票時, ):

值不能爲空。參數名:看起來像他們小號

+0

什麼是** CLR **? – Chax

+1

@Chax公共語言運行時。基本上是每個.NET程序的「覆蓋」實現 –

0

即使框架擴展的方法將拋出一個NullReferenceException,而不是扔ArgumentNullExceptions

List<string> list = null; 
var results = list.Select(x => x); //ArgumentNullException 

從剛纔看代碼(和不事先知道選擇是一個擴展法)這個應該拋出NullReferenceException ...如果框架不即使在這種情況下扔,我會一直堅持使用ArgumentNullException

1

NullReferenceException從不故意拋出按慣例。它表示無意的預防違規。因此,它幾乎總是表示一個錯誤。該錯誤在引發異常的代碼中。

全部NullReferenceException s應按照慣例視爲錯誤。其中99%是真正的錯誤。 1%不是真正的錯誤,但是值得花時間來阻止它們並且拋出更有意義的異常類型來維護這個約定。使用Argument*Exception表示您拒絕傳遞的參數。 NullReferenceException意味着引發此異常的代碼的程序員犯了一個錯誤。

NullReferenceException視爲運行時提供的失敗斷言。 Argument*Exception的意思是「我想過這個案子,我有意識地拒絕它。」