Meine Frage als Titel oben. Zum Beispiel,
IEnumerable<T> items = new T[]{new T("msg")};
items.ToList().Add(new T("msg2"));
aber es hat doch nur 1 artikel drin.
Können wir eine Methode wie haben items.Add(item)
?
wie List<T>
c#
list
ienumerable
ldsenow
quelle
quelle
IEnumerable<T>
ist nur zum Abfragen von Sammlungen gedacht. Es ist das Rückgrat für das LINQ-Framework. Es ist immer eine Abstraktion von einer anderen Sammlung wieCollection<T>
,List<T>
oderArray
. Die Schnittstelle bietet nur eineGetEnumerator
Methode, die eine Instanz zurückgibtIEnumerator<T>
, mit der die erweiterte Sammlung einzeln durchlaufen werden kann. Die LINQ-Erweiterungsmethoden sind durch diese Schnittstelle begrenzt.IEnumerable<T>
ist schreibgeschützt, da es eine Ansammlung von Teilen mehrerer Sammlungen darstellen kann.IList<T>
anstelle vonIEnumerable<T>
:IList<T> items = new T[]{new T("msg")}; items.Add(new T("msg2"));
Antworten:
Sie können nicht, da
IEnumerable<T>
dies nicht unbedingt eine Sammlung darstellt, zu der Elemente hinzugefügt werden können. Tatsächlich handelt es sich nicht unbedingt um eine Sammlung! Zum Beispiel:Sie können jedoch ein neues
IEnumerable
Objekt (vom nicht angegebenen Typ) erstellen , das bei Aufzählung alle Elemente des alten sowie einige Ihrer eigenen Objekte bereitstellt. Sie verwendenEnumerable.Concat
dafür:Dadurch wird das Array-Objekt nicht geändert (Sie können ohnehin keine Elemente in Arrays einfügen). Es wird jedoch ein neues Objekt erstellt, das alle Elemente im Array auflistet, und dann "Foo". Darüber hinaus verfolgt dieses neue Objekt Änderungen im Array (dh, wann immer Sie es aufzählen, werden die aktuellen Werte von Elementen angezeigt).
quelle
Concat
wird wiederholt in einer Schleife aufgerufen. und wennConcat
ja, haben Sie ohnehin größere Probleme, weil Sie jedes Mal eine weitere Aufzählungsebene erhalten. Am Ende führt der einzelne Aufruf von zuMoveNext
einer Aufrufkette, deren Länge der Anzahl der Iterationen entspricht.IEnumerable<T>
in C #, einschließlich Überladungoperator+
alsConcat
(übrigens, wissen Sie, dass Sie in VB indizieren können,IEnumerable
als wäre es ein Array - es wirdElementAt
unter der Haube verwendet): connect.microsoft.com / VisualStudio / feedback /… . Wenn wir auch zwei weitere Überladungen bekommenConcat
, um einen einzelnen Gegenstand sowohl links als auch rechts zu nehmen, würde dies die Eingabe reduzierenxs +=x
- also stupse Mads (Torgersen) an, um dies in C # 5.0 zu priorisieren :)Der Typ
IEnumerable<T>
unterstützt solche Operationen nicht. Der Zweck derIEnumerable<T>
Schnittstelle besteht darin, einem Verbraucher das Anzeigen des Inhalts einer Sammlung zu ermöglichen. Die Werte nicht ändern.Wenn Sie Vorgänge wie .ToList (). Add () ausführen, erstellen Sie eine neue
List<T>
und fügen dieser Liste einen Wert hinzu. Es besteht keine Verbindung zur ursprünglichen Liste.Was Sie tun können, ist die Erweiterungsmethode Hinzufügen, um eine neue
IEnumerable<T>
mit dem Mehrwert zu erstellen .Auch in diesem Fall wird das ursprüngliche
IEnumerable<T>
Objekt nicht geändert . Dies kann überprüft werden, indem ein Verweis darauf gehalten wird. Zum BeispielNach diesem Satz von Operationen verweist die Variable temp immer noch nur auf eine Aufzählung mit einem einzelnen Element "foo" im Wertesatz, während Elemente auf eine andere Aufzählung mit den Werten "foo" und "bar" verweisen.
BEARBEITEN
Ich vergesse immer wieder, dass Add keine typische Erweiterungsmethode ist,
IEnumerable<T>
da es eine der ersten ist, die ich am Ende definiere. Hier ist esquelle
Concat
:)Add
, daAdd
bei praktisch jedem anderen .NET-Typ (nicht nur Sammlungen) die Sammlung an Ort und Stelle mutiert. VielleichtWith
? Oder es könnte sogar nur eine weitere Überlastung seinConcat
.Concat
Überlastung wahrscheinlich die bessere Wahl wäre, da diesAdd
normalerweise Veränderlichkeit impliziert.return e.Concat(Enumerable.Repeat(value,1));
?Haben Sie darüber nachgedacht, stattdessen
ICollection<T>
oderIList<T>
Schnittstellen zu verwenden, existieren diese genau aus dem Grund, aus dem Sie eineAdd
Methode für eine haben möchtenIEnumerable<T>
.IEnumerable<T>
wird verwendet, um einen Typ als ... gut, aufzählbar oder nur als eine Folge von Elementen zu markieren, ohne unbedingt zu garantieren, ob das eigentliche zugrunde liegende Objekt das Hinzufügen / Entfernen von Elementen unterstützt. Denken Sie auch daran, dass diese Schnittstellen implementiert werden,IEnumerable<T>
sodass Sie auch alle Erweiterungsmethoden erhalten, mit denen Sie arbeitenIEnumerable<T>
.quelle
Ein paar kurze, süße Verlängerungsmethoden
IEnumerable
undIEnumerable<T>
mach es für mich:Elegant (naja, bis auf die nicht generischen Versionen). Schade, dass diese Methoden nicht in der BCL enthalten sind.
quelle
ToString()
darauf, da dadurch mehr Fehlerdetails erfasst werden. Ich würde vermuten, dass Sie nicht ganzinclude System.Linq;
oben in Ihrer Akte standen, aber wer weiß? Versuchen Sie es selbst herauszufinden, erstellen Sie einen Mindestprototyp, der denselben Fehler aufweist, wenn Sie dies nicht können, und bitten Sie dann bei einer Frage um Hilfe.In .net Core gibt es eine Methode
Enumerable.Append
, die genau das tut.Der Quellcode der Methode ist auf GitHub verfügbar. .... Die Implementierung (ausgefeilter als die Vorschläge in anderen Antworten) ist einen Blick wert :).
quelle
Nein, die IEnumerable unterstützt das Hinzufügen von Elementen nicht.
Ihre "Alternative" ist:
quelle
Um eine zweite Nachricht hinzuzufügen, müssen Sie -
quelle
Sie können nicht nur keine Elemente hinzufügen, wie Sie angeben, sondern wenn Sie ein Element zu einer
List<T>
(oder so ziemlich jeder anderen nicht schreibgeschützten Sammlung) hinzufügen, für die Sie einen vorhandenen Enumerator haben, wird der Enumerator ungültig (wirftInvalidOperationException
fortan).Wenn Sie Ergebnisse aus einer Datenabfrage aggregieren, können Sie die
Concat
Erweiterungsmethode verwenden:Bearbeiten: Ich habe ursprünglich die
Union
Erweiterung im Beispiel verwendet, was nicht wirklich korrekt ist. Meine Anwendung verwendet es ausgiebig, um sicherzustellen, dass überlappende Abfragen keine doppelten Ergebnisse liefern.quelle
Ich komme nur hierher, um zu sagen, dass es neben der
Enumerable.Concat
Erweiterungsmethode eine andere Methode mit dem NamenEnumerable.Append
.NET Core 1.1.1 zu geben scheint . Mit letzterem können Sie ein einzelnes Element mit einer vorhandenen Sequenz verknüpfen. So kann Aamols Antwort auch geschrieben werden alsBeachten Sie jedoch, dass diese Funktion die Eingabesequenz nicht ändert, sondern lediglich einen Wrapper zurückgibt, der die angegebene Sequenz und das angehängte Element zusammenfügt.
quelle
Andere haben bereits großartige Erklärungen gegeben, warum Sie nicht in der Lage sein können (und sollten!), Elemente zu einem hinzuzufügen
IEnumerable
. Ich will nur noch hinzufügen , dass , wenn Sie Codierung an eine Schnittstelle weiterhin suchen, der eine Sammlung und wollen ein Add - Methode darstellt, sollten Sie codierenICollection
oderIList
. Als zusätzliche Goldgrube implementieren diese SchnittstellenIEnumerable
.quelle
du kannst das.
quelle
Der einfachste Weg, dies zu tun, ist einfach
Dann können Sie list als IEnumerable zurückgeben, auch weil es die IEnumerable-Schnittstelle implementiert
quelle
Wenn Sie Ihr Objekt als
IEnumerable<int> Ones = new List<int>();
Dann erstellen, können Sie dies tun((List<int>)Ones).Add(1);
quelle
Sicher können Sie (ich lasse Ihr T-Geschäft beiseite):
quelle