簡體   English   中英

帶有未初始化的可為空類型的Enumerable Min和Max擴展方法行為所迷惑

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM