2011-06-20 59 views
9

我試圖使用Enumerable.SequenceEqual(x,y),因爲我預計它的工作基於 Object.Equals(x,y)方法,如果x或y爲空則返回false,如果兩者都爲null(對於null情況)則返回true。爲什麼Enumerable.SequenceEqual在任何參數爲null時拋出異常?

但是Enumerable.SequenceEqual(x,y)如果任何參數爲空引用,則拋出異常,如果給定兩個空值,則不會返回true。

在我的代碼檢查集合平等經常所以我創建了一個方法,模仿的序列Object.Equals的行爲,但我只是想知道什麼背後的違約行爲邏輯,並有可能對空值沒有例外現有的方法?

+1

那麼,第一個參數爲null的事實會引發異常,這是有道理的,因爲它是一種擴展方法。它通常被調用爲'x.SequenceEqual(y)',因此模仿'x.Equals(y)',如果'x'在'null'處也會拋出。 –

回答

4

那麼,MSDN documentation明確指出,它將拋出一個ArgumentNullException萬一任何一個傳入的序列爲空。我認爲這是爲了保持與「標準行爲」的一致性,當你試圖對其進行解引用時,對象拋出NullReferenceException。試想一下:

List<int> foo = null; 
foo.SequenceEqual(new List<int>()); 

這將是確定爲SequenceEqual是一個擴展方法,因此可以處理一個空的對象,但它也將是混亂的。就我所知,Linq提供的每種擴展方法都遵循這種行爲。您也不需要爲每個擴展方法處理特殊的空情況(您需要就明智的行爲達成一致並添加額外的邏輯並對其進行維護和測試)。說它是非法的,這使得它更健壯(針對邏輯錯誤),並從框架的角度來看是一致的。我使用Linq很多,從來沒有遇到過這個問題 - 我只是確保我所有的序列不爲空。大量減少代碼混亂(從代碼中刪除大量的空檢查)。

2

檢查序列相等性的時間點並不是在拋出異常時。它被提前作爲一個論證驗證者拋出。考慮方法:

public static bool SequenceEquals<T>(this IEnumerable<T> source, IEnumerable<T> target) 
{ 
    // Stuff 
} 

我們明確需要檢查sourcetarget不是空的,因爲如果其中任何一樣,那麼我們不能檢查序列平等。這是一個不可行的狀態,SequenceEquals的結果應該由可枚舉的內容來管理,而不是可枚舉的狀態。如果它包含後者,當返回false時,由於序列不相同,或者一個或兩個枚舉項是否爲null,調用者將如何知道它實際上是否失敗?

如果我們在這裏沒有拋出ArgumentNullException,當您嘗試訪問null枚舉值之一時,CLR將拋出NullReferenceException。簡單地說,Object reference not set to an instance of an objectThe argument <something> cannot be null要少得多。

請記住,拋出異常的類型通常是最有用的指標之一爲什麼拋出了異常。

相關問題