89

I have the following method:

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

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

Why is it that when I do .Count() above it is underlined in red?

I got the following error:

Error 1 'System.Collections.Generic.IEnumerable' does not contain a definition for 'Count' and no extension method 'Count' accepting a first argument of type 'System.Collections.Generic.IEnumerable' could be found (are you missing a using directive or an assembly reference?) c:\users\a\documents\visual studio 2010\Projects\NerdDinner\NerdDinner\Models\Dinner.cs 15 47 NerdDinner

Keith Pinson
  • 7,835
  • 7
  • 61
  • 104
aherlambang
  • 14,290
  • 50
  • 150
  • 253
  • Had same problem. For some reason you can't right-click this and choose "Resolve ..." to fix it :( – micahhoover Apr 23 '13 at 21:31
  • Sigh! I have System.Linq included but still get this error. (Though he error message names the first arg as "System.Linq.IQueryable".) – Hot Licks Apr 08 '14 at 18:08
  • On a general note: Be way of the shortcomings of .Count() - don't use it lightheartedly! I've written about it in my comment below https://stackoverflow.com/a/65112753/863651 Feel free to review it – XDS Dec 02 '20 at 17:25

5 Answers5

174

You add:

using System.Linq;

at the top of your source and make sure you've got a reference to the System.Core assembly.

Count() is an extension method provided by the System.Linq.Enumerable static class for LINQ to Objects, and System.Linq.Queryable for LINQ to SQL and other out-of-process providers.

EDIT: In fact, using Count() here is relatively inefficient (at least in LINQ to Objects). All you want to know is whether there are any elements or not, right? In that case, Any() is a better fit:

public bool IsValid
{
  get { return !GetRuleViolations().Any(); }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • If this reference gives you an error, verify that the Target Framework of your project (in the project properties, Application tab) is set to .NET Framework 3.5 or 4. Extension methods won't work on 2.0 or earlier. – willvv Apr 17 '10 at 17:26
  • 1
    I've had the using System.Linq; but it doesn't resolve my issue... how can I make sure that I got a reference to the System.Core assembly? – aherlambang Apr 17 '10 at 17:26
  • Oh nevermind, I fixed it... what is the different between System.data.linq and System.Linq – aherlambang Apr 17 '10 at 17:27
  • @Alexander: They're entirely different namespaces. `System.Data.Linq` is specific to LINQ to SQL. – Jon Skeet Apr 17 '10 at 17:29
  • Maybe it should be revised in the NerdDinner tutorial that I am using as it uses Count instead of Any – aherlambang Apr 17 '10 at 17:39
  • @Alexander: Quite possibly :) – Jon Skeet Apr 17 '10 at 18:25
  • @skyfoot: I have no idea what you're referring to. Where is it out by 1? – Jon Skeet Sep 08 '11 at 15:49
  • 1
    @skyfoot: No, it really won't. It will give you 4. If you think otherwise, please post a question with a short but complete program which demonstrates the problem. – Jon Skeet Sep 08 '11 at 16:32
  • Applying the extension method Count to IEnumerable is problematic since an IEnumerable may contain an infinite number of elements, e.g. IEnumerable GetInfinite() { while (true) yield return 0; } – bbudge Mar 05 '15 at 21:06
10

Any() or Count() methods in Linq work only for generic types.

IEnumerable<T>

If you have a simple IEnumerable without a type, try to use

IEnumerable<object> 

instead.

Saeb Amini
  • 23,054
  • 9
  • 78
  • 76
Renzo Ciot
  • 3,746
  • 2
  • 25
  • 29
2

IEnumeration does not have a method called Count(). It's just a kind of "sequence of elements". Use for example List if you explicitly need the number of elements. If you use Linq keep in mind, that the extension method Count() may actually re-count the number of elements each time you call it.

Danvil
  • 22,240
  • 19
  • 65
  • 88
0

A short & sweet general word of caution on the pitfalls of .Count() to help the weary traveler that stumbles upon this post in the future!

Short story:

The following works -no doubt- but there might small performance penalty if the enumerables is not backed by an underlying array or list which has the 'count' in handy/precomputed:

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

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

The call to the .Count() method will probably go through each and every item in the enumerable and then compare the overall count against threshold. We being smarter can do a bit better:

    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()
    }

There! Problem solved again but this time around we are performance-conscious!

XDS
  • 3,786
  • 2
  • 36
  • 56
-1

How about:

public bool IsValid
{
    get { return (GetRuleViolations().Cast<RuleViolation>().Count() == 0); }
}
Kulvir
  • 524
  • 4
  • 5