やりたかったこと
LINQとnull条件演算子を合わせ、要素がなかったらnullを返してほしい。次の式でemp=nullになると期待。
>var lst = new List<int>(); >var emp = lst.Where(e => e > 0)?.Min(); シーケンスに要素が含まれていません + System.Linq.Enumerable.Min(IEnumerable<int>)
nullとはならずSystem.InvalidOperationExceptionが投げられました。
期待通りの結果を得る
まずは期待通りの結果を得る方法。
> var emp = lst.Where(e => e > 0).Min(e => (int?)e); > emp null
Minでnull許容型に変換すると要素がない場合nullが帰ってきます。
勘違い
Whereの結果、空ならnullと思っていましたがWhereListIteratorですね。
> var lst = new List<int>(); > var emp = lst.Where(e => e > 0); > emp.GetType() [System.Linq.Enumerable+WhereListIterator`1[System.Int32]]
class WhereListIterator<TSource> : Iterator<TSource> abstract class Iterator<TSource> : IEnumerable<TSource>, IEnumerator<TSource>
ドキュメントにも戻り値はIEnumerable
その他適当に調べたこと
int?型のタイプを調べるときはGetType()を使わない。
> int? a = 0; > a.GetType() [System.Int32]
値が入ってるとint型
> int? a = null; > a.GetType() オブジェクト参照がオブジェクト インスタンスに設定されていません。 + object.GetType()
nullだと例外。
Null許容型を識別する方法
配列のリスト
> var lst = new List<int[]>(); > lst.Where(e => e[0] > 0) Enumerable.WhereListIterator<int[]> { } > lst.Where(e => e[0] > 0).Min(e => e[0]) シーケンスに要素が含まれていません + System.Linq.Enumerable.Min(IEnumerable<int>) > lst.Where(e => e[0] > 0).Min(e => e?[0]) null
DefaultIfEmpty
シーケンスが空の場合設定した値、設定しない場合規定値を持つシングルトンコレクションを返す。
> var lst = new List<int>(); > lst.Where(e=>e>0).DefaultIfEmpty() DefaultIfEmptyIterator { 0 } > lst.Where(e => e > 0).DefaultIfEmpty(5) DefaultIfEmptyIterator { 5 }
> var lst = new List<int[]>(); > lst.Where(e => e[0] > 0).DefaultIfEmpty() DefaultIfEmptyIterator { null } > lst.Where(e=>e[0]>0).DefaultIfEmpty().Min() null > lst.Where(e => e[0] > 0).DefaultIfEmpty().Min(e=>e[0]) オブジェクト参照がオブジェクト インスタンスに設定されていません。 + System.Linq.Enumerable.WhereSelectEnumerableIterator<TSource, TResult>.MoveNext() + System.Linq.Enumerable.Min(IEnumerable<int>) + System.Linq.Enumerable.Min<TSource>(IEnumerable<TSource>, Func<TSource, int>) > lst.Where(e => e[0] > 0).DefaultIfEmpty().Min(e => e?[0]) null > lst.Where(e => e[0] > 0).DefaultIfEmpty(new int[] { 1, 2 }) DefaultIfEmptyIterator { int[2] { 1, 2 } }
所感
今回の風古戦場やばない?ヤバババババムートじゃない?