web-dev-qa-db-ja.com

C#リストでの.Any()の使用<>

私はこれについて同僚と話し合っており、C#で特定の_.Any_に対して _List<>_ がどのように使用されるかを理解できませんでした。

次のステートメントのように、配列内の要素の有効性を確認できます。

_if (MyList.Any()){ ...}  //Returns true or false
_

これはまったく同じです

_if (MyList.Count() != 0) { ... }
_

また、ifステートメントの意図について、より一般的で読みやすく、明確です。

結局、私たちはこの考えに行き詰まりました。

.Any()を使用できますが、同様に機能しますが、プログラマーの意図が明確ではないため、使用しないでください。

しかし、これは正しくないように思えます。何かが足りないはずです。

私たちは?

44
Gil Sand

AnyListを操作しないことに注意してください。これはIEnumerableを操作します。これは、Countプロパティを持つ場合と持たない場合がある具象型を表します。 Listで使用するのが必ずしも最良の方法ではないことは事実ですが、LINQクエリの最後に使用すると間違いなく便利です。スタンドアロンバージョンよりもさらに便利なのは、Whereと同じように述語を取るオーバーライドです。 Listには、述語-Any拡張メソッドほど便利で表現力のあるものは何も組み込まれていません。

また、CountListのプロパティ)ではなくCount()(IEnumerableのLINQ拡張メソッド)を使用している場合は、全体を列挙する必要があります。シーケンス 基になるデータ型にCountプロパティがあることを検出してこれを最適化できない場合 。シーケンスが長い場合、カウントが何であるか本当に気にせず、anyコレクション内のアイテム。

99
Mason Wheeler

実行時間には違いがありますCount()はO(n)の場合があります。ここでAny()はO(1)です。

56
Sign

実際には、 List.Count プロパティがあり、次に Enumerable.Count メソッドがあることを覚えておいてください。

あなたの例では、Enumerable.Count()メソッドを使用しています。このメソッドは、列挙のすべての項目を反復して結果を返す必要があります。これは、最初の項目が存在する場合にそれを反復するだけでよいAny()を呼び出すよりも明らかに低速です。

編集:

コメントで指摘されたとおり、Enumerable.Count()拡張メソッドは、列挙型もICollection<T>。したがって、List<T>Countプロパティまたはメソッドを使用しても、実際には違いはありません。

IEnumerable.Count ソース:

public static int Count<TSource>(this IEnumerable<TSource> source) {
    if (source == null) throw Error.ArgumentNull("source");
    ICollection<TSource> collectionoft = source as ICollection<TSource>;
    if (collectionoft != null) return collectionoft.Count;
    ICollection collection = source as ICollection;
    if (collection != null) return collection.Count;
    int count = 0;
    using (IEnumerator<TSource> e = source.GetEnumerator()) {
        checked {
            while (e.MoveNext()) count++;
        }
    }
    return count;
}
9
sstan

意外な質問-list.Any()の意図はlist.Count()!=0の意図よりもはるかに明確であると思います。

意図する意味:誰かがコードを読んだ場合(そして自分でコードを記述しなかった場合)、プログラマーが達成したいことと、それがなぜそのように書かれたのかが完全に明らかですか?一般的な問題が不必要に複雑な方法で解決されると、すぐに疑わしくなり、開発者がなぜ単純な方法を使用しなかったのか疑問に思います。あなたはコードを調べて、何かを見逃していないかどうかを確認しようとします。不足している副作用があり、変更すると予期しない問題が発生する可能性があるため、コードを変更することを恐れています。

Any()メソッドを使用する意図は完全に明確です。リストに要素があるかどうかを知りたい場合。

一方、式Count()!=0の意図は、読者には明らかではありません。もちろん、式がリストが空であるかどうかを示していることを確認するのは難しくありません。質問は、標準的な方法を使用するのではなく、この特定の方法で記述するために発生します。 Count()を明示的に使用するのはなぜですか?リストにany要素があるかどうかを本当に知りたいだけの場合、なぜ最初にリスト全体を数えたいのですか? 1に達するとすぐに、すでに答えがあります。ソースが大きな(おそらく無限の)コレクションに対するイテレータであるか、SQLに変換されている場合、パフォーマンスに大きな違いをもたらす可能性があります。それで、Count()の明示的な使用は、遅延クエリを強制的に実行するか、イテレータをトラバースすることですか?

しかし、ソースは実際には_List<T>_であり、ここでCount()はO(1)であり、副作用はありません。ただし、コードが_List<T>_、それでは、Count- propertyを使用して、O(1)演算に副作用がないことを期待していることをより明確に示しますか?

記述されているように、list.Count()!=0list.Any()とまったく同じように動作しますが、不必要により複雑であり、意図が明確ではありません。

6
JacquesB

多分それはただの言葉ですか? Anyは形容詞であり、実際には何も言っていません。 Javaから来て、動詞を含むisNonEmptyと呼びます。 SQLの人はEXISTSを好むかもしれません。しかし、おそらくAnyはC#システムに最適です。

Wordの選択が何であれ、慣れれば、それはmustより明確になります。 「ありますかmore than zeroビール瓶が残っています。 "を期待しますone or more「いいえ、anyはありません」と回答する前にカウントを開始した人はいますか?

2
maaartinus