2015-11-04 44 views
7

我有以下代碼,試圖捕獲空引用。然後它會拋出一個異常,並帶有更明確的消息屬性中指定的錯誤原因。IndexNotFoundException與NullReferenceException

什麼樣的例外應該它扔?一個IndexOutOfRangeException

var existing = this.GetByItemId(entity.ItemId); // int or long 
if (existing == null) 
{ 
    throw new IndexOutOfRangeException("The specified item does not exist."); 
} 

var price = existing.Price; 

or a NullReferenceException

var existing = this.GetByItemId(entity.ItemId); 
if (existing == null) 
{ 
    throw new NullReferenceException("The specified item does not exist."); 
} 

var price = existing.Price; 

或者,我們應該讓這個異常順其自然嗎?

var existing = this.GetByItemId(entity.ItemId); 
var price = existing.Price; // NullReferenceException coming your way 

我們往往不這樣做最後的選擇的原因是,默認的NullReferenceException是在細節上的光,只是指出

對象引用不設置到對象的實例。

說實話,這可能是C#中最無用的錯誤信息。

+2

在您的代碼中,IndexOutOfRangeException似乎不適合:在使用整數索引訪問可索引結構(數組,列表)時,我期待這樣的異常,並且使用的索引超出範圍。 你的'GetItemById(int itemID)'似乎使用了一個查找的東西的id,而不是一個整數,因爲索引 –

+0

是'存在的'null或是'existing.Price' null,它們會完全不同。然而,你的例子表明了這兩種方式。 –

+0

如果缺少空引用異常中的細節,也許您會想要繼承它並使用您需要的屬性創建自己的異常?或者只是任何舊的自定義異常與一些豐富的描述,這可能是我會做... – Culme

回答

9

我會用這個自定義異常(有些東西一樣ItemNotFoundException)。

一個NullReferenceExceptionIndexOutOfRangeException可能通過this.GetByItemId()內或框架別處的東西被拋出。

如果項目沒有出現在集合中(例如添加它),調用者可能希望執行後續操作。 使用您自己的異常允許調用者catch具體例外,並作出相應的反應。

+0

我已經採取了你的意見。我們現在有一個ItemNotFoundException。 – Junto

5

與您所選擇的描述自定義異常應該這樣做:

if (existing == null) 
    { 
     throw new EntityMissingException("'existing' does not exist (ironic, isn't it?)."); 
    } 
+2

永遠不要拋出所有異常的基類。這使得編寫集中的catch塊成爲不可能。 –

+1

我真的很感興趣,爲什麼這是downvoted =)該OP認爲,NullReferenceException是「光明細節」。如果需要,使用自定義錯誤文本可以提供很多細節。同意的是,它在處理等方面有缺點,但它真的很糟糕嗎?我傾向於這麼做,所以我真的很欣賞指出爲什麼它不好,我不只是因爲我被壓低了而咆哮! =) – Culme

+0

謝謝@Daniel。我本來應該用不太快而骯髒的自定義錯誤來代替,你可能是對的。 – Culme

1

NullReferenceException表示您想要訪問空引用的成員。通常你不應該拋出它(除非你實現了一個解釋器或類似的東西)。

如果entity是一個參數,那麼我會說這是一個ArgumentException。如果你說這在正常情況下不會發生,那麼這是一個InvalidOperationException