2010-09-09 28 views
8

有人可以解釋這裏發生了什麼嗎? Howcome 這兩個這些事情是真的嗎?LINQ可空類型的聚集行爲

[TestMethod] 
public void WhatIsGoingOnHere() 
{ 
    List<int?> list = new List<int?> { 1, 2, 3, null, 5, 6 }; 
    Assert.AreEqual(17, list.Sum()); 

    int? singleSum = 1 + 2 + 3 + null + 5 + 6; 

    Assert.IsNull(singleSum); 
} 

具體來說,爲什麼Sum()方法不返回'null'?或者singleSum不等於17?

+0

+1有趣的問題! – 2010-09-09 04:35:26

回答

4

你所看到的是使用Enumerable.Sum和自己實際添加值之間的差異。

這裏重要的是null不爲零。乍一看,你會認爲 應該等於17,但這意味着我們將不得不根據引用的數據類型分配不同的語義到null。事實上,這是一個int?沒有區別 - nullnull,並且不應該在語義上等於數字常數0

Enumerable.Sum的實現旨在跳過序列中的任何值null,這就是爲什麼您會看到兩個測試之間的不同行爲。然而第二個測試正確地返回null,因爲編譯器足夠聰明以知道向null添加任何東西會產生null

這裏是接受的int?參數的Enumerable.Sum實現:

public static int? Sum(this IEnumerable<int?> source) 
{ 
    if (source == null) 
    { 
     throw Error.ArgumentNull("source"); 
    } 
    int num = 0; 
    foreach (int? nullable in source) 
    { 
     // As you can see here it is explicitly designed to 
     // skip over any null values 
     if (nullable.HasValue) 
     { 
      num += nullable.GetValueOrDefault(); 
     } 
    } 
    return new int?(num); 
} 
+0

我完全理解爲什麼singelSum是null,而不是17--因爲null只是null ...完全和你在一起:)我想我的問題更多,Sum()如何不返回null ... – kiwipom 2010-09-09 04:36:48

6

可空類型的.Sum()方法忽略所有null值:

MSDN:Enumerable.Sum Method (IEnumerable<Nullable<Int32>>)

備註

結果不包括爲空值。

如果通過+添加任何數量null而結果是null

正如Andrew Hare指出的那樣,向null添加數字沒有意義:null不是0;它只是不是一個數字。

+0

感謝您的鏈接...看起來它只是它的工作原理。我現在得到 - 乾杯:) – kiwipom 2010-09-09 04:37:14

+0

真誠抱歉,我無法將這些答案都標記爲正確的... +1,無論如何!謝謝 – kiwipom 2010-09-09 04:42:39