Null許容型でLINQでSumやらAverageするときに注意すべきコト
どー言うことか?
IEnumerable<Nullable<T>>
に対して、Sum()やらAverage()やら使うと個人的に予想外の結果になったのでその備忘録。
Nullableに関して
NumericなNullableに対して、BinaryOperationを実行した場合、片っぽがnullなら伝播して、結果はnullに成る。
int? x=42;
int? y=114514;
int? z=null;
//114556が出力される。
Console.WriteLine((x + y)?.ToString() ?? "NULL");
//NULLが出力される。
Console.WriteLine((x + z)?.ToString() ?? "NULL");
で、本題
さて、Ienumerable<int?>
見たいなシーケンスにSum
やらAverage
を適用したらどうなるだろうかってのが今日のお題。
Nullが紛れ込んでなきゃ何の問題も無いけど、紛れ込んでいた場合を検証してみた。
int?[] nonNullArray=Enumerable.Range(0,10).Select(x=>(int?)x).ToArray();
int?[] nullArray=nonNullArray.ToArray();
nullArray[9]=null;
int?[] allNullArray=Enumerable.Repeat((int?)null,10).ToArray();
//45
Console.WriteLine(nonNullArray.Sum());
//4.5
Console.WriteLine(nonNullArray.Average());
//9
Console.WriteLine(nonNullArray.Max());
//0
Console.WriteLine(nonNullArray.Min());
Console.WriteLine();
//36
Console.WriteLine(nullArray.Sum());
//4
Console.WriteLine(nullArray.Average());
//8
Console.WriteLine(nullArray.Max());
//0
Console.WriteLine(nullArray.Min());
Console.WriteLine();
//0
Console.WriteLine(allNullArray.Sum());
//null
Console.WriteLine(allNullArray.Average());
//null
Console.WriteLine(allNullArray.Min());
//null
Console.WriteLine(allNullArray.Max());
概ねこんなかんじになる。
以上のことから、
- 要素に
null
が有る場合、フィルタされる。-
Sum()
の場合、nullはフィルタされるので、nullの要素以外の合計となる。 -
Average()
の場合、上記の合計をnull
以外の要素数で除した結果となる。 -
Min()
、Max()
は不感
-
- すべての要素が
null
の場合、Sum()
は0を返す。 -
Average()
,Max()
,Min()
はnull
を返す。
まとめ
以上の検証から、nullの要素は基本的にフィルタされて処理されることがわかった。
全要素がnullの場合は、Sum()は0を返し、Sum()以外はnullを返すので、ちょいと注意が必要かと。
要素にnullが存在する場合、結果がnullに成ることを企図したければ、事前にAnyあたりで、当たりを付けるか、Aggregateで処理するか、素直にforeachに展開するが良いかと思います。
Author And Source
この問題について(Null許容型でLINQでSumやらAverageするときに注意すべきコト), 我々は、より多くの情報をここで見つけました https://qiita.com/Tokeiya/items/01edd91c2611ee67315f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .