Was sind die Hauptunterschiede zwischen IEnumerable
Count()
und Length
?Unterschied zwischen IEnumerable Count() und Länge
Antwort
Mit dem Aufruf Count auf IEnumerable<T>
nehme ich an, dass Sie sich auf die Erweiterungsmethode Count
auf System.Linq.Enumerable
beziehen. Length
ist keine Methode auf IEnumerable<T>
sondern eher eine Eigenschaft auf Array-Typen in .Net wie int[]
.
Der Unterschied ist die Leistung. Die Eigenschaft Length
ist garantiert eine O (1) -Operation. Die Komplexität der Erweiterungsmethode Count
hängt vom Laufzeittyp des Objekts ab. Es wird versucht, auf mehrere Typen zu transformieren, die eine 0 (1) -Längensuche wie ICollection<T>
über eine Count
-Eigenschaft unterstützen. Wenn keine verfügbar sind, wird es alle Elemente aufzählen und sie zählen, die eine Komplexität von O (N) hat.
Zum Beispiel
int[] list = CreateSomeList();
Console.WriteLine(list.Length); // O(1)
IEnumerable<int> e1 = list;
Console.WriteLine(e1.Count()); // O(1)
IEnumerable<int> e2 = list.Where(x => x <> 42);
Console.WriteLine(e2.Count()); // O(N)
Der Wert e2
ist als C# Iterator implementiert, die nicht O (1) das Zählen und damit das Verfahren Count
muss die gesamte Sammlung aufzuzählen unterstützt, um zu bestimmen, wie lang es ist.
Kleiner Zusatz zu Jon Skeet 's Kommentar.
Es gibt Quellcode Count()
Erweiterungsmethode:
.NET 3:
public static int Count<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
ICollection<TSource> is2 = source as ICollection<TSource>;
if (is2 != null)
{
return is2.Count;
}
int num = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
num++;
}
}
return num;
}
.NET 4:
public static int Count<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
ICollection<TSource> is2 = source as ICollection<TSource>;
if (is2 != null)
{
return is2.Count;
}
ICollection is3 = source as ICollection;
if (is3 != null)
{
return is3.Count;
}
int num = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
num++;
}
}
return num;
}
Beachten Sie, dass in .NET 4 auch ein anderer Block für den nicht generischen 'ICollection'-Typ vorhanden ist. (Da dies auch eine "Count" -Eigenschaft hat.) –
@ Jon Skeet: Danke – bniwredyc
Weiß jemand was zu 'verwenden', um die' Fehler' Klasse zu bekommen, die diese Methode verwendet? Ich kann es nirgendwo auf MSDN finden, außer in der JScript-Dokumentation. –
Länge ist eine feste Eigenschaft, z.B. eines eindimensionalen Arrays oder einer Zeichenfolge. Es ist also nie eine Zähloperation erforderlich (multidimensionale Arrays haben eine Größe aller Dimensionen multipliziert). O (1) Operation bedeutet hier, dass die Suchzeit immer gleich ist, egal wie viele Elemente es gibt. Eine lineare Suche wäre (im Gegensatz dazu) O (n).
Der Count-Eigenschaft auf ICollections (List und List <T>, zum Beispiel) kann sich ändern, so hat es entweder auf Hinzufügen aktualisiert werden/Entfernen Operationen oder als Graf nach der Sammlung angefordert wird, hat sich geändert. Hängt von der Implementierung des Objekts ab.
Die Count() -Methode von LINQ iteriert grundsätzlich JEDES Mal, wenn sie aufgerufen wird (außer wenn das Objekt ein ICollection-Typ ist, dann wird die ICollection.Count-Eigenschaft angefordert).
Beachten Sie, dass IEnumerables ist oft nicht bereits Objektsammlungen definiert (wie Listen, Arrays, Hash-Tabellen etc.), aber Link zu Hintergrundoperationen, die Ergebnisse erzeugen, wenn sie angefordert werden (verzögerte Ausführung bezeichnet).
Typischerweise haben Sie eine SQL wie LINQ-Anweisung wie folgt aus (die typische Anwendung von verzögerte Ausführung):
IEnumerable<Person> deptLeaders =
from p in persons
join d in departments
on p.ID equals d.LeaderID
orderby p.LastName, p.FirstName
select p;
Dann gibt es Code wie folgt:
if (deptLeaders.Count() > 0)
{
ReportNumberOfDeptLeaders(deptLeaders.Count());
if (deptLeaders.Count() > 20)
WarnTooManyDepartmentLeaders(deptLeaders.Count());
}
Also, wenn eine Warnung für zu viele Abteilungsleiter wird ausgegeben, .NET geht VIERMAL durch die Personen, prüft sie gegen die Abteilungsleiter, sortiert sie nach Namen und zählt dann die Ergebnisobjekte.
Und dies ist nur, wenn Personen und Abteilungen Preset-Wert-Sammlungen sind, nicht selbst Abfragen.
Ich könnte hinzufügen, dass '.Count()> 0 'ist das gleiche wie' .Any() '. – jedmao
@sfjedi: Ich denke, es ist nicht das Gleiche. Any() stoppt, wenn ein Element gefunden wurde, während Count() durch alle iteriert. Wenn IEnumerable für eine verzögerte Ausführung möglich ist, sollte Any() für die Leerprüfung bevorzugt werden. –
Wäre '.Any()' dann effizienter als '.Count()> 0'? BTW, Resharper beschwert sich immer über '.Count()> 0'. Deshalb bringe ich es zuversichtlich zur Sprache. – jedmao
- 1. Praktischer Unterschied zwischen List und IEnumerable
- 2. Unterschied zwischen Größe und Länge Methoden?
- 3. IEnumerable keine Count-Methode
- 4. Was ist der Unterschied zwischen IEnumerable und Arrays?
- 5. Was ist der Unterschied zwischen count (0), count (1) .. und count (*) in mySQL/SQL?
- 6. Count selectlist items (zähle IEnumerable)
- 7. .net Namenskonvention: Gibt es einen semantischen Unterschied zwischen Länge und Anzahl?
- 8. JS Count Titel Länge
- 9. Unterschied zwischen = und: =
- 10. Unterschied zwischen @Size, @Length und @Column (Länge = Wert)
- 11. Unterschied zwischen MATLAB die Anzahl und Länge Funktionen
- 12. In SQL, was ist der Unterschied zwischen count (*) und count ('x')?
- 13. In Perl, was ist der Unterschied zwischen "wenn definiert $ count" und "if $ count"?
- 14. Im Android-Speicher-Monitor, was ist der Unterschied zwischen `total count` und` heap count`?
- 15. LEFT JOIN und COUNT zwei Abfragen Unterschied
- 16. Unterschied zwischen IsGenericType und IsGenericTypeDefinition
- 17. Unterschied zwischen Attributrichtlinie und Elementeigenschaftensyntax?
- 18. numpy count wo der Unterschied zwischen Werten größer als etwas
- 19. Was ist der Unterschied zwischen IEnumerable und Array, IList und List?
- 20. Unterschied zwischen Vorzeichen & und *?
- 21. VBA: Unterschied zwischen & und +
- 22. Unterschied zwischen "**/* /" und "** /"?
- 23. Unterschied zwischen $ # und $ {# @}
- 24. Unterschied zwischen '#', '%' und '$'
- 25. MySQL: Unterschied zwischen ', `,' und '
- 26. C++ Unterschied zwischen '//' und '///'
- 27. Unterschied zwischen String.Empty und ""
- 28. Unterschied zwischen `% in%` und `==`
- 29. Unterschied zwischen numpy.logical_and und &
- 30. Unterschied zwischen. und #
'Liste' hat keine Eigenschaft Länge - es hat eine Count-Eigenschaft. Arrays haben jedoch eine 'Länge'. 'Count' wird in' ICollection' und 'ICollection ' angegeben (welches 'IList ' erweitert). –
@ Jon, doh. Ich werde den Mangel an Schlaf hier verantwortlich machen. Wird update – JaredPar
Und wenn Ihre 'IEnumerable' ist unendlich lang, 'Count()' wird nie zurückkehren ... –