IEnumerableにはCountメソッドがありません


83

私は次の方法を持っています:

public bool IsValid
{
  get { return (GetRuleViolations().Count() == 0); }
}

public IEnumerable<RuleViolation> GetRuleViolations(){
  //code here
}

.Count()上で行うと赤で下線が引かれているのはなぜですか?

次のエラーが発生しました:

エラー1「System.Collections.Generic.IEnumerable」に「Count」の定義が含まれておらず、「System.Collections.Generic.IEnumerable」タイプの最初の引数を受け入れる拡張メソッド「Count」が見つかりませんでした(ディレクティブまたはアセンブリ参照を使用していますか?)c:\ users \ a \ documents \ visual studio 2010 \ Projects \ NerdDinner \ NerdDinner \ Models \ Dinner.cs 15 47 NerdDinner


同じ問題がありました。何らかの理由で、これを右クリックして「解決...」を選択して修正することはできません:(
micahhoover 2013

はぁ!System.Linqが含まれていますが、それでもこのエラーが発生します。(エラーメッセージでは最初の引数に「System.Linq.IQueryable」という名前が付けられていますが。)
Hot Licks 2014

一般的な注意事項:.Count()の欠点を回避してください-気楽に使用しないでください!私はそれについて以下のコメントに書いていますstackoverflow.com/a/65112753/863651お気軽にレビューしてください
XDS 2010

回答:


160

あなたが追加します:

using System.Linq;

ソースの上部にあり、System.Coreアセンブリへの参照があることを確認してください。

Count()は、System.Linq.EnumerableLINQ to Objects、およびSystem.Linq.QueryableLINQ toSQLおよびその他のアウトプロセスプロバイダーの静的クラスによって提供される拡張メソッドです。

編集:実際、Count()ここでの使用は比較的非効率的です(少なくともLINQ to Objectsでは)。あなたが知りたいすべてがあるかどうかである任意の権利、要素かどうかは?その場合、Any()より適切です:

public bool IsValid
{
  get { return !GetRuleViolations().Any(); }
}

この参照でエラーが発生した場合は、プロジェクトのターゲットフレームワーク(プロジェクトのプロパティの[アプリケーション]タブ)が.NET Framework3.5または4に設​​定されていることを確認してください。拡張メソッドは2.0以前では機能しません。
willvv 2010

1
System.Linqを使用しました。しかし、それは私の問題を解決しません... System.Coreアセンブリへの参照を取得したことを確認するにはどうすればよいですか?
aherlambang 2010

気にしないでください、私はそれを修正しました... System.data.linqとSystem.Linqの違いは何
ですか

@Alexander:それらは完全に異なる名前空間です。System.Data.LinqLINQ toSQLに固有です。
Jon Skeet 2010

1
@skyfoot:いいえ、実際にはありません。それはあなたに4を与えるでしょう。そうでないと思うなら、問題を実証する短いが完全なプログラムで質問を投稿してください。
Jon Skeet 2011

7

Any()またはCount()Linqのメソッドは、ジェネリック型に対してのみ機能します。

IEnumerable<T>

IEnumerableタイプのないシンプルなものをお持ちの場合は、

IEnumerable<object> 

代わりに。


2

IEnumerationと呼ばれるメソッドはありませんCount()。それは一種の「要素のシーケンス」です。たとえばList、要素の数が明示的に必要な場合に使用します。Linqを使用する場合、拡張メソッドCount()は、呼び出すたびに要素の数を実際に再カウントする可能性があることに注意してください。


0

将来この投稿に出くわす疲れた旅行者を助けるための.Count()の落とし穴に関する短くて甘い一般的な注意の言葉

ショートストーリー:

以下は-間違いなく-動作しますが、列挙型が便利な/事前計算された「カウント」を持つ基になる配列またはリストによって裏付けられていない場合、パフォーマンスわずかに低下する可能性があります。

public bool IsValid
{
   get { return SomeMethodReturningEnumerable().Count() <= threshold; }  <--- small performance issue here
}

public IEnumerable<SomeObject> SomeMethodReturningEnumerable(){
   yield return foo;
   yield return bar; etc
}

.Count()メソッドの呼び出しは、おそらく列挙にそれぞれすべての項目を経るとなり、その後、閾値に対して、全体の数を比較します。私たちが賢くなると、もう少しうまくいくことができます。

    public bool IsValid
    {
       get { return !SomeMethodReturningEnumerable().HasMoreThan(threshold); }  <--- neato!
    }

    public static bool HasLessThan<T>(this IEnumerable<T> sequence, int count) => !sequence.HasMoreThan(count - 1);

    public static bool HasLessOrEqualTo<T>(this IEnumerable<T> sequence, int count) => !sequence.HasMoreThan(count);

    public static bool HasMoreOrEqualTo<T>(this IEnumerable<T> sequence, int count) => sequence.HasMoreThan(count - 1);

    public static bool HasMoreThan<T>(this IEnumerable<T> sequence, int count) => sequence.EnumerationCounterImpl(count, equals_vs_greaterThan: false);

    public static bool HasExactly<T>(this IEnumerable<T> sequence, int count) => sequence.EnumerationCounterImpl(count, equals_vs_greaterThan: true);

    public static bool EnumerationCounterImpl<T>(this IEnumerable<T> sequence, int count, bool equals_vs_greaterThan = true) //0
    {
        if (equals_vs_greaterThan && count < 0)
            throw new ArgumentException($"{nameof(count)} is less than zero!");

        if (!equals_vs_greaterThan && count < 0)
            return true;

        var staticCount = (sequence as ICollection)?.Count                              
                          ?? (sequence as ICollection<T>)?.Count
                          ?? (sequence as IReadOnlyCollection<T>)?.Count;

        if (staticCount != null)
            return staticCount > count;

        using (var enumerator = sequence.GetEnumerator()) //1 optimization
        {
            for (int i = 0; i < count + 1; i++)
            {
                if (enumerator.MoveNext())
                    continue;

                return false;
            }

            return !equals_vs_greaterThan //     ==
                   || enumerator.MoveNext(); //  >
        }

        //0 https://blog.slaks.net/2015-01-12/linq-count-considered-occasionally-harmful/
        //1 using the enumerator directly is slightly faster than using LINQ methods   it avoids allocating an extra iterator
        //  state machine compared to using skip()
    }

そこ!問題は再び解決しましたが、今回はパフ​​ォーマンスを重視しています。


-1

どうですか:

public bool IsValid
{
    get { return (GetRuleViolations().Cast<RuleViolation>().Count() == 0); }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.