IEnumerable nie ma metody Count


83

Mam następującą metodę:

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

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

Dlaczego jest tak, że kiedy robię .Count()powyżej, jest podkreślony na czerwono?

Otrzymałem następujący błąd:

Błąd 1 „System.Collections.Generic.IEnumerable” nie zawiera definicji „Count” i nie można znaleźć metody rozszerzającej „Count” akceptującej pierwszy argument typu „System.Collections.Generic.IEnumerable” (czy brakuje using dyrektywy lub odwołanie do zestawu?) c: \ users \ a \ documents \ visual studio 2010 \ Projects \ NerdDinner \ NerdDinner \ Models \ Dinner.cs 15 47 NerdDinner


Miałem ten sam problem. Z jakiegoś powodu nie możesz kliknąć tego prawym przyciskiem myszy i wybrać „Rozwiąż ...”, aby to naprawić :(
micahhoover

Westchnienie! Mam dołączony System.Linq, ale nadal pojawia się ten błąd. (Chociaż komunikat o błędzie nazywa pierwszy argument „System.Linq.IQueryable”.)
Hot Licks

Ogólna uwaga: uważaj na wady .Count () - nie używaj go beztrosko! Pisałem o tym w komentarzu poniżej stackoverflow.com/a/65112753/863651 Zapraszam do recenzji
XDS

Odpowiedzi:


160

Dodajesz:

using System.Linq;

u góry źródła i upewnij się, że masz odwołanie do zestawu System.Core.

Count()jest metodą rozszerzającą udostępnianą przez System.Linq.Enumerableklasę statyczną dla LINQ to Objects iSystem.Linq.Queryable dla LINQ to SQL i innych dostawców poza procesem.

EDYCJA: W rzeczywistości użycie Count()tutaj jest stosunkowo nieefektywne (przynajmniej w LINQ to Objects). Wszystko, co chcesz wiedzieć, to czy są jakieś elementy, czy nie, prawda? W takim przypadku Any()lepiej pasuje:

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

Jeśli to odwołanie powoduje błąd, sprawdź, czy platforma docelowa projektu (we właściwościach projektu, na karcie Aplikacja) jest ustawiona na .NET Framework 3.5 lub 4. Metody rozszerzające nie będą działać w wersji 2.0 lub starszej.
willvv

1
Miałem using System.Linq; ale to nie rozwiązuje mojego problemu ... jak mogę się upewnić, że mam odniesienie do zestawu System.Core?
aherlambang

Och, nieważne, naprawiłem to ... jaka jest różnica między System.data.linq i System.Linq
aherlambang

@Alexander: To zupełnie różne przestrzenie nazw. System.Data.Linqjest specyficzny dla LINQ to SQL.
Jon Skeet

1
@skyfoot: Nie, naprawdę nie będzie. To da ci 4. Jeśli myślisz inaczej, zadaj pytanie z krótkim, ale kompletnym programem, który demonstruje problem.
Jon Skeet,

7

Any()lub Count()metody w Linq działają tylko dla typów ogólnych.

IEnumerable<T>

Jeśli masz prosty IEnumerablebez typu, spróbuj użyć

IEnumerable<object> 

zamiast.


2

IEnumerationnie ma metody o nazwie Count(). To po prostu rodzaj „sekwencji elementów”. Użyj na przykład, Listjeśli wyraźnie potrzebujesz liczby elementów. Jeśli używasz Linq, pamiętaj, że metoda rozszerzenia Count()może w rzeczywistości ponownie policzyć liczbę elementów za każdym razem, gdy ją wywołasz.


0

Krótkie i słodkie ogólne ostrzeżenie na temat pułapek .Count (), aby pomóc zmęczonemu podróżnikowi, który natknie się na ten post w przyszłości!

Krótka historia:

Poniższe działa - bez wątpienia - ale może wystąpić niewielki spadek wydajności, jeśli wyliczenia nie są poparte podstawową tablicą lub listą, która ma `` liczbę '' w podręcznej / wstępnie obliczonej:

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

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

Wywołanie metody .Count () prawdopodobnie przejdzie przez każdy element wyliczalny, a następnie porówna ogólną liczbę z wartością progową. Jesteśmy mądrzejsi, możemy zrobić trochę lepiej:

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

Tam! Problem rozwiązany ponownie, ale tym razem zwracamy uwagę na wydajność!


-1

Co powiesz na:

public bool IsValid
{
    get { return (GetRuleViolations().Cast<RuleViolation>().Count() == 0); }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.