MSDN > 論壇首頁 > LINQ Project General > Why Sum over Nullable return Nullable in same time as Min over real values throw exceptions for empty collections ?
發問發問
 

已答覆Why Sum over Nullable return Nullable in same time as Min over real values throw exceptions for empty collections ?

  • 2005年9月18日 下午 11:47TAG 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

    This is two related questions:

    a) Why Sum over  int?  return nullable int?  not a regular ?

    In this example

    int? a = null;

    int? b = 1;

    var check = a+b; // Result in null

    int?[] numbers = { a, b};

    var numSum = numbers.Sum();  // Result in 1

    Value of numSum  is 1 - but value of check is null. 

    What is a reason to return nullable int in case if null-value never expected ?

     

    b)  Why it was decided to throw EmptySequenceException for some of agreegate operators like a  Min(this IEnumerable<long> source)  but not for their friends IEnumerable< Nullable<long> >  ?

    int?[] numbers = {};

    var numSum = numbers.Min(); // Result in null

    int[] numbers2 = {};

    var numSum2 = numbers2.Min(); // Result in costly exception

    Why such a difference ? Why not return Nullable<long> in both situations or throw exception in both ?

     

    So - can somebody clarify how it was decided to use Nullable return values for LINQ functions ?

解答

  • 2005年9月20日 上午 04:40Anders Hejlsberg 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     已答覆
    Actually, I misspoke on (a) above. Sum ignores null values in the source sequence, but it never returns null. If a sequence is empty or contains only nulls, the result is zero. We could in theory return int from Sum(IEnumerable<int?>), but it would break with the pattern of returning the same type as the element type of the sequence.

    Anders

所有回覆

  • 2005年9月20日 上午 04:06Anders Hejlsberg 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

    Regarding (a), the reason Sum(IEnumerable<int?>) returns int? (and not int) is that the result is null if the source is empty or contains only nulls.

    Regarding (b), if the source is an enumerable of a non-nullable type, it seems appropriate for the result to also be a non-nullable type. You can always use the Min, Max, or Average method with a lambda argument to produce a sequence of a nullable type and a nullable result. For example:

    int[] numbers = { 1, 2, 3, 4, 5 };
    int? minNum = numbers.Min(x => (int?)x);

    Anders

  • 2005年9月20日 上午 04:40Anders Hejlsberg 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     已答覆
    Actually, I misspoke on (a) above. Sum ignores null values in the source sequence, but it never returns null. If a sequence is empty or contains only nulls, the result is zero. We could in theory return int from Sum(IEnumerable<int?>), but it would break with the pattern of returning the same type as the element type of the sequence.

    Anders
  • 2005年9月20日 下午 12:38TAG 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     

    Hmm..  What is a reason for such a filtering ?  This is inconsistent - as Sum(a,b) != a + b   as well there is no way to figure out if sequence is empty (your trick with  x => (int?)x) does not work - all that we can get is exception or 0 value.
    Current filtering can easily done with   Where(x => x!=null).Sum(). 

    My proposal is to:
    Sum(IEnumerable<int> x)  to return  int?  , null-value will indicate empty sequence. 
    Sum(IEnumerable<int?> x) to return int?  as sum of values or null in case if there no any element or at least one nullable is inside.

    This will make it possible to use thouse operators inside nested queries. At the moment this is risky as this can result in exceptions.

    I do not know high-level design goals - so my idea can be flawed. But it's definitely valuable - as current implementations can be obtained easily    (int) Sum(IE..<int>)  and Where(x => x!=null).Sum()??0   while others options are allowed.