LINQにはラムダで条件式を渡し、要素全てがその条件を満たしているかを判定してboolを返す、All()
という便利なメソッドがあります。
List<int>list1=newList<int>{1,2,3};if(list1.All(n=>n>0))// ← 要素が全て0より大きいのでtrue{Console.WriteLine("正の整数です");}// 出力: 正の整数です
空のリストに対してこのメソッドを実行すると、直感とは異なる挙動になります。
(「全てが満たす」だからfalseになると思っていた)
List<int>list2=newList<int>();if(list2.All(n=>n>0))// ← true{Console.WriteLine("正の整数です");}// 出力: 正の整数です
All()
の実装を見てみると、リストの要素が空の場合は必ずtrueが返るようになっていました。Any()
等を組み合わせて判定するのが安全そうです。
// https://github.com/microsoft/referencesource/blob/master/System.Core/System/Linq/Enumerable.cs#L1305publicstaticboolAll<TSource>(thisIEnumerable<TSource>source,Func<TSource,bool>predicate){if(source==null)throwError.ArgumentNull("source");if(predicate==null)throwError.ArgumentNull("predicate");foreach(TSourceelementinsource){// ← sourceの要素が0なのでループが回らないif(!predicate(element))returnfalse;}returntrue;// ← ので、必ずtrueが返る}
List<int>list2=newList<int>();if(list2.Any()&&list2.All(n=>n>0))// ← false{Console.WriteLine("正の整数です");}