Was ist ein solides, elegant, wieder verwendbares Stück Code zu bestimmen, ob ein IEnumerable leer ist, in .NET?

StackOverflow https://stackoverflow.com/questions/117355

  •  02-07-2019
  •  | 
  •  

Frage

Ich versuche, die meisten wiederverwendbar, dennoch elegant zu finden, ein Stück Code möglich, wenn ein IEnumerable zu bestimmen. Im Ideal soll dies eine Funktion sein, die ich jederzeit absolut anrufen kann ich sagen müssen, wenn ein IEnumerable leer ist.

Während ich eine Antwort für .NET 3.5 entwickelt habe, die für mich bisher gut gearbeitet hat, mein derzeitiger Gedanke ist, dass es keine perfekte Antwort, da ein IEnumerable technisch eine Sammlung (oder eine Warteschlange von Iteratoren) einkapseln, Das ändert die zugrunde liegende Ergebnisse, wie es iteriert, was zu Problemen führen würde. Dies würde aber auch ein Hindernis sein, um die Umsetzung IEnumerable.Count (), und das hat nicht MS stoppt sie bereitstellt.

Also dachte ich, ich es so setzen würde, um zu sehen, ob jemand ein besseres hat, und falls jemand anderes sollte es nützlich finden.

Edit: Wow, ich kann nicht glauben, dass ich nicht über IEnumerable.Any wusste. Ich wusste, dass es existiert, aber nie die Mühe gemacht, um zu überprüfen, was es getan hat. Lass dir das eine Lehre sein. Lesen Sie die Dokumentation. Nur weil ein Methodenname bedeutet nicht, es tut, was Sie wollen, bedeutet nicht, es nicht tun, was Sie wollen.

War es hilfreich?

Lösung

!enumerable.Any()

Es wird versucht, nur das erste Element zu greifen.

Um sich zu erweitern, wie / warum das funktioniert, bestimmt jeder, wenn eine der Komponenten eines IEnumerable eine gegebene Funktion entsprechen, falls keine angegeben wurde, dann wird jede Komponente erfolgreich sein, kehrt die Funktion Bedeutung true, wenn ein Element in der existiert enumerable.

Andere Tipps

Für .net 1/2:

IEnumerator e;
try
{
   e = enumerable.GetEnumerator();
   return e.MoveNext();
}
finally
{ 
    if (e is IDisposable)
        e.Dispose();
}

Oder mit Generika:

using (IEnumerator<T> e = enumerable.GetEnumerator())
{
    return e.MoveNext();
}

Sie haben Recht, dass es keine perfekte Antwort. IEnumerable unterstützt nur Iteration und garantiert nicht, dass die Aufzählung wiederholbar ist. Sie können nicht herausfinden, ob ein Aufzählungselemente enthält Movenext mindestens einmal ohne Aufruf, und sobald Sie getan haben, so können Sie nicht in der Lage sein garantieren die Aufzählung wieder zu verwenden: es zulässig ist, für IEnumerable.Reset eine NotSupportedException zu werfen. Aus http://msdn.microsoft.com/en -US / library / system.collections.ienumerator.reset.aspx :

„Die Reset-Methode für COM-Interoperabilität zur Verfügung gestellt Es muss nicht unbedingt umgesetzt werden müssen;.. Stattdessen kann der Implementierer einfach eine NotSupportedException werfen“

Erweiterungsmethoden wie IEnumerable .Count und IEnumerable .Any müssen Movenext unter der Decke nennen. Nützliche Wrapper, aber nicht vermeiden, dass in den (seltenen) Fällen, in denen eine Aufzählung nicht Zurücksetzen nicht unterstützt, könnten Sie ein Problem haben.

Eine Sache, vorsichtig mit einer der folgenden Methoden zu sein, dass nicht alle Aufzählungen zurückgerollten werden kann, zum Beispiel alle Implementierungen von System.Data.IDataReader nur einmal durchlaufen kann.

In diesen Fällen Sie nicht wirklich eine Kosten in einer foreach Schleife haben, so lange, wie Sie die Tatsache berücksichtigen, dass es vielleicht nicht einmal Schleife einmal.

Die erste Methode hat eine einfache Implementierung von leerer Erweiterungsmethode: http://signum.codeplex.com/SourceControl/changeset/view/25903# 510468

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top