[英]Why is Enumerable Min or Max inconsistent between collections of reference and value types?
[英]Bewildered by Enumerable Min and Max extension methods behavior with uninitialized nullable types
有人可以闡明(或自由推測)為什么Linq Min和Max擴展方法在處理未初始化的可空類型時會表現出它們的行為嗎?
也許最簡單的方法是顯示我觀察到的內容:
int? a = null;
int? b = 1;
Nullable.Compare(a, b); // -1, indicating null is smaller then 1
new int?[] { null, 1 }.OrderBy(x => x).First(); // null, null smaller then 1
new[] { 0, 1 }.Min(); // 0 as expected
new int[] { }.Min(); // invalidoperator exception as expected
到目前為止一切順利,但隨后...
new int?[] { null, 1 }.Max(); // 1 as expected
new int?[] { null, 1 }.Min(); // 1 ?????, why not null ?
new int?[] { null, null }.Min(); // null, why null now and not above ?
new int?[] { }.Min(); // null, and no exception ???
我承認,我一開始並不特別在意Nullable類型,但這是另一個故事:-)
我仍然對為什么以這種方式實施感到好奇。
干杯,巴特
您可以反編譯Nullable源代碼,從而得到以下定義:
public static int Compare<T>(Nullable<T> n1, Nullable<T> n2) where T : struct
{
if (n1.HasValue) {
if (n2.HasValue) return Comparer<T>.Default.Compare(n1.value, n2.value);
return 1;
}
if (n2.HasValue) return -1;
return 0;
}
看起來nullable.compare方法在n1為null和n2具有值的情況下有意返回-1。
同樣,您可以反編譯linq源代碼,從而得到以下定義:
public static int? Min(this IEnumerable<int?> source) {
if (source == null) throw Error.ArgumentNull("source");
int? value = null;
foreach (int? x in source) {
if (value == null || x < value)
value = x;
}
return value;
}
源對象上的迭代檢查值是否為null,如果為null,則將x分配給value *。 這只是linq的默認實現,它是在與null進行比較時返回一個數字作為最小值。
關於為什么要這樣做的問題,我認為這是因為null表示缺少值而不是整數值,並且他們(編寫linq的人)不同意可比方法的最初構建方式。 他們可能發現沒有正常執行路徑,其中空將被認為是最好的回答“什么是空值和整數的這個列表的最小值 ”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.