MSDN > Home page del forum > LINQ Project General > Why Sum over Nullable return Nullable in same time as Min over real values throw exceptions for empty collections ?
Formula una domandaFormula una domanda
 

Con rispostaWhy Sum over Nullable return Nullable in same time as Min over real values throw exceptions for empty collections ?

  • domenica 18 settembre 2005 23.47TAG Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     

    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 ?

Risposte

  • martedì 20 settembre 2005 4.40Anders Hejlsberg Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Con risposta
    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

Tutte le risposte

  • martedì 20 settembre 2005 4.06Anders Hejlsberg Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     

    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

  • martedì 20 settembre 2005 4.40Anders Hejlsberg Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Con risposta
    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
  • martedì 20 settembre 2005 12.38TAG Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     

    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.