2015-12-29 26 views
3

考慮以下幾點:爲什麼在一個空的引用列表上調用Min()不會拋出?

var emptyValueList = new List<int>(); //any value type (long, float, any struct ...) 
var minimum = emptyValueList.Min(); 

這將引發InvalidOperationException序列不包含任何元素)。

現在讓我們嘗試用一個引用類型:

var emptyReferenceList = new List<object>(); //any ref type will do such as object ... 
var minimum = emptyReferenceList.Min(); 

這不丟,並返回null。這就好像default運營商被召入第二個案例,但不是第一個。它也適用於可空類型(例如int?,即使它們是值類型)。

我在想,爲什麼會出現這種情況,以及這背後是否有特定的理由?

+0

新名單();詮釋?意味着它是可空的,那就是它沒有拋出任何錯誤的原因 – Se0ng11

+1

不滿意的答案當然就是這些功能被記錄爲[要](https://msdn.microsoft.com/en-us/ library/bb339189(v = vs.110).aspx)[do](https://msdn.microsoft.com/en-us/library/bb341201(v = vs.110).aspx) –

回答

6

這是一個設計決定,我們將不得不問BCL的作者。

Min extension method有各種過載。對於允許null的類型,我相信Min在搜索最小值時會跳過所有null值。這適用於兩種參考類型和type Nullable<>(在您的示例Nullable<int>中),它不是參考類型,但允許null(即Min方法決定忽略)。

與非空的結構

所以,Min作者可能認爲這將是「危險的」返回default(TSource),因爲這可能是一個meaningfull(即非空)最低在其他情況下(通常是數0),和因此輸出可能會被誤解。

隨着類型,允許null,因爲作者選擇了跳過從源頭上得到null值,一個可以安全地假設,如果該序列包含什麼,但null值(包括帶空的源代碼的情況下)null只能返回。


注意,根據標準的用於IComparer<>空類型或引用類型,所述null值小於任何非空值。對於排序算法(如List<>.Sort使用的算法),訂單必須是全部和傳遞的。因此,我們得到:

Console.WriteLine(
    Comparer<int?>.Default.Compare(null, 7) 
    ); // "-1" 

    Console.WriteLine(
    Nullable.Compare((int?)null, 7) 
    ); // "-1" 


    Console.WriteLine(
    new List<int?> { 9, null, 7, 13, } 
    .OrderBy(ni => ni).First() 
    ); // "" 


    // 'Min' is special in that it disregards 'null' values 
    Console.WriteLine(
    new List<int?> { 9, null, 7, 13, } 
    .Min() 
    ); // "7" 

而且Min適用於真正的引用類型相同的方式,例如System.Version(這是一個class型):

var li = new List<Version> { new Version("9.0"), null, new Version("7.0"), new Version("13.0"), }; 

    Console.WriteLine(li.OrderBy(ve => ve).First()); 
    Console.WriteLine(li.Min()); 
+1

有趣的是,沒有知道'Min'(和'Max'我猜)的特殊行爲。聽起來像是對各個sql聚合函數進行求和。 –

相關問題