[解決済み】LINQ:Not Any vs All Don't
質問
提供された値がリスト内の値と一致するかどうかをチェックしたいことがよくあります (たとえばバリデーションのとき)。
if (!acceptedValues.Any(v => v == someValue))
{
// exception logic
}
最近、ReSharperがこれらのクエリを簡略化するように要求してくるのに気づいた。
if (acceptedValues.All(v => v != someValue))
{
// exception logic
}
明らかに、これは論理的に同一で、おそらく(あなたが数学をたくさんやったのなら)よりわずかに読みやすいでしょう。私の質問は、これがパフォーマンスヒットにつながるかどうかということです。
そうすべきな気がします(つまり
.Any()
は短絡しているように聞こえるのに対し
.All()
のような気がするのですが、これを証明するものはありません。どなたか、この2つのクエリが同じように解決するのか、あるいはReSharperが私を迷わせるのかについて、深い知識をお持ちの方はいらっしゃいますか?
解決方法は?
の実装
All
ILSpyによると(実際に行って見てみると、quot;まあ、その方法はちょっと..."のように動作します。) 私たちが影響ではなく理論を議論している場合、そうするかもしれません。
public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (predicate == null)
{
throw Error.ArgumentNull("predicate");
}
foreach (TSource current in source)
{
if (!predicate(current))
{
return false;
}
}
return true;
}
の実装
Any
ILSpyによる。
public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (predicate == null)
{
throw Error.ArgumentNull("predicate");
}
foreach (TSource current in source)
{
if (predicate(current))
{
return true;
}
}
return false;
}
もちろん、生成されるILに微妙な違いがある可能性もあります。しかし、いや、そんなことはない。ILはほとんど同じですが、述語が一致したときにtrueを返すのと、述語が不一致のときにfalseを返すのとが明らかに逆になっています。
もちろん、これはlinq-for-objectsだけの話です。他のlinqプロバイダーが一方を他方よりずっと良く扱っている可能性もありますが、もしそうだとしたら、どちらがより最適な実装を得たかはかなりランダムです。
このルールは、ただ単に誰かが
if(determineSomethingTrue)
よりもシンプルで読みやすい。
if(!determineSomethingFalse)
. そして、公平に見て、彼らの言うことも少しはもっともだと思うのですが、私はよく
if(!someTest)
同じように冗長で複雑な代替テストがある場合、そのテストが真を返したとき、我々は混乱します。しかし、個人的には、あなたが挙げた2つの選択肢のうち、どちらかを支持するものは何もありませんし、おそらく述語がもっと複雑であれば、ごくわずかに前者に傾くでしょう。
*しかし、私が理解できない決定には何か微妙な理由があるのではないかと心配になり、「いや、彼らはただそのようにすることに決めただけなんだ、ちょっと待って、私は何のためにこのコードのビットを見ていたんだ..."」と気づくのに数回の精神的スキップが必要になるという意味で混乱する。
関連
-
[解決済み】「The breakpoint will not currently be hit」を改善するには?このドキュメントにはシンボルが読み込まれていません。" という警告はどうすれば改善されますか?
-
[解決済み】クロススレッド操作が有効でない。作成されたスレッド以外のスレッドからアクセスされたコントロール
-
[解決済み] LINQを使用してList<T>から要素を削除する
-
[解決済み] LINQで複数の "order by "を使用する
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] LINQのGroup by
-
[解決済み] DataTableに対するLINQクエリ
-
[解決済み] LINQで.Firstと.FirstOrDefaultを使用するタイミングは?
-
[解決済み] LINQ集計アルゴリズム説明
-
[解決済み】LINQを使用してコレクション内のすべてのオブジェクトを更新する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Ajax処理で「無効なJSONプリミティブ」と表示される件
-
[解決済み] 保護レベルによりアクセス不能になりました。
-
[解決済み】C# ASP.NET使用時に「WebClientのリクエスト中に例外が発生しました。
-
[解決済み】バックスラッシュを含むパス文字列のエスケープシーケンスが認識されない件
-
[解決済み】ORA-01008: すべての変数がバインドされていません。これらはバインドされています。
-
[解決済み】Entity FrameworkからのSqlException - セッション内で他のスレッドが動作しているため、新しいトランザクションは許可されません。
-
[解決済み】ファイルやアセンブリ、またはその依存関係の1つをロードできませんでした。
-
[解決済み】プロセスが実行されているかどうかを知るには?
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である
-
[解決済み】スレッド終了またはアプリケーションの要求により、I/O操作が中断されました。