Frage

Meine Frage als Titel oben. Zum Beispiel:

IEnumerable<T> items = new T[]{new T("msg")};
items.ToList().Add(new T("msg2"));

, aber schließlich ist es nur 1 Punkt im Innern.

Können wir eine Methode, wie items.Add(item)?

wie die List<T>

War es hilfreich?

Lösung

Sie können nicht, weil IEnumerable<T> nicht notwendigerweise eine Sammlung darstellen, auf die Elemente hinzugefügt werden können. In der Tat stellt es muss nicht unbedingt eine Sammlung überhaupt! Zum Beispiel:

IEnumerable<string> ReadLines()
{
     string s;
     do
     {
          s = Console.ReadLine();
          yield return s;
     } while (s != "");
}

IEnumerable<string> lines = ReadLines();
lines.Add("foo") // so what is this supposed to do??

Was Sie tun können, ist jedoch erstellen neue IEnumerable Objekt (nicht näher bezeichneten Art), die, wenn sie aufgezählt, alle Elemente des alten bieten wird, sowie einige der eigenen. Sie verwenden Enumerable.Concat dafür:

 items = items.Concat(new[] { "foo" });
Diese

nicht ändern wird das Array-Objekt (Sie können keine Elemente einfügen in auf Arrays, sowieso). Aber es wird ein neues Objekt zu erstellen, das alle Elemente in der Array-Liste, und dann „Foo“. Darüber hinaus, dass neues Objekt Überblick über Änderungen in der Anordnung hält (das heißt, wenn Sie es aufzuzählen, werden Sie die aktuellen Werte der Einzelteile sehen).

Andere Tipps

Der Typ IEnumerable<T> unterstützt keine solche Operationen. Der Zweck der IEnumerable<T>-Schnittstelle ist ein Verbraucher zu ermöglichen, den Inhalt einer Sammlung anzuzeigen. Nicht die Werte zu ändern.

Wenn Sie Operationen wie .ToList tun (). Add () Sie einen neuen List<T> erstellen und einen Wert zu dieser Liste hinzuzufügen. Es hat keine Verbindung zu der ursprünglichen Liste.

Was Sie tun können, ist die Add-Extension-Methode verwenden, um eine neue IEnumerable<T> mit dem Mehrwert zu schaffen.

items = items.Add("msg2");

Auch in diesem Fall wird es das ursprüngliche IEnumerable<T> Objekt nicht ändern. Dies kann, indem eine Referenz darauf überprüft werden. Zum Beispiel

var items = new string[]{"foo"};
var temp = items;
items = items.Add("bar");

Nach dieser Reihe von Operationen die Variable Temp wird nur noch eine zählbare mit einem einzigen Element „foo“ in dem Satz von Referenzwerten, während Elemente eine andere zählbare mit Werten „foo“ verweisen, und „bar“.

Bearbeiten

ich vergessen contstantly dass Add keine typische Erweiterungsmethode auf IEnumerable<T> ist, weil es eine der ersten, die ist, die ich definieren, enden. Hier ist sie

public static IEnumerable<T> Add<T>(this IEnumerable<T> e, T value) {
  foreach ( var cur in e) {
    yield return cur;
  }
  yield return value;
}

Haben Sie mit in Betracht gezogen ICollection<T> oder IList<T> Schnittstellen statt, es gibt sie aus dem Grund, dass Sie auf eine Add Methode haben wollen ein IEnumerable<T>.

IEnumerable<T> wird als ... na ja, zählbare oder einfach nur eine Folge von Elementen, ohne notwendigerweise irgendwelche Garantien, ob die reale Aufgabe zugrunde, unterstützt das Hinzufügen / Entfernen von Elementen ‚Marke‘ eine Art verwendet. Denken Sie auch daran, dass diese Schnittstellen IEnumerable<T> implementieren, damit Sie alle Erweiterungen Methoden, die Sie mit IEnumerable<T> bekommen auch.

Ein paar kurze, süße Erweiterungsmethoden auf IEnumerable und IEnumerable<T> es für mich tun:

public static IEnumerable Append(this IEnumerable first, params object[] second)
{
    return first.OfType<object>().Concat(second);
}
public static IEnumerable<T> Append<T>(this IEnumerable<T> first, params T[] second)
{
    return first.Concat(second);
}   
public static IEnumerable Prepend(this IEnumerable first, params object[] second)
{
    return second.Concat(first.OfType<object>());
}
public static IEnumerable<T> Prepend<T>(this IEnumerable<T> first, params T[] second)
{
    return second.Concat(first);
}

Elegant (gut, mit Ausnahme der Nicht-Generika-Versionen). Schade, diese Methoden sind nicht in der BCL.

Nein die IEnumerable unterstützt keine Gegenstände sie hinzufügen.

Sie 'Alternative' ist:

var List = new List(items);
List.Add(otherItem);

In .net Core gibt es ein Verfahren Enumerable.Append, die das tut genau.

Der Quellcode des Verfahrens ist auf GitHub. .... Die Implementierung (anspruchsvoller als die Vorschläge in anderen Antworten) ist ein Blick wert :).

Zum zweiten Nachricht hinzufügen Sie müssen -

IEnumerable<T> items = new T[]{new T("msg")};
items = items.Concat(new[] {new T("msg2")})

Sie können nicht nur Artikel nicht hinzufügen, wie Sie angeben, aber wenn Sie ein Element in einem List<T> hinzufügen (oder so ziemlich jede andere Nicht-Nur-Lese-Sammlung), die Sie für eine bestehende enumerator haben, wird der Enumerator für ungültig erklärt (wirft InvalidOperationException von da an).

Wenn Sie ergibt sich aus einer Art von Datenabfrage werden aggregiert, können Sie die Concat Erweiterungsmethode verwenden:

Edit: Ich habe ursprünglich die Union Erweiterung in dem Beispiel, das nicht wirklich korrekt ist. Meine Anwendung verwendet sie ausgiebig, um sicherzustellen, überlappende Abfragen Ergebnisse nicht dupliziert werden.

IEnumerable<T> itemsA = ...;
IEnumerable<T> itemsB = ...;
IEnumerable<T> itemsC = ...;
return itemsA.Concat(itemsB).Concat(itemsC);

ich hier nur kommen zu sagen, dass, abgesehen von Enumerable.Concat Erweiterungsmethode scheint es 1.1.1 eine andere Methode namens Enumerable.Append in .NET-Core zu sein. Letzteres ermöglicht es Ihnen, ein einzelnes Element zu einer vorhandenen Sequenz verketten. So Aamol Antwort kann auch geschrieben werden

IEnumerable<T> items = new T[]{new T("msg")};
items = items.Append(new T("msg2"));

Still Bitte beachten Sie, dass diese Funktion nicht die Eingangssequenz ändern, es zurückgeben nur einen Wrapper, der die angegebene Reihenfolge und den beigefügten Artikel zusammen.

Andere haben bereits große Erklärungen gegeben in Bezug auf, warum Sie können (und sollten nicht!) In der Lage sein, Produkte zu einem IEnumerable hinzuzufügen. 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 auf ICollection oder IList . Als zusätzlichen Bonanza, implementieren diese Schnittstellen IEnumerable.

Sie können dies tun.

//Create IEnumerable    
IEnumerable<T> items = new T[]{new T("msg")};

//Convert to list.
List<T> list = items.ToList();

//Add new item to list.
list.add(new T("msg2"));

//Cast list to IEnumerable
items = (IEnumerable<T>)items;

Der einfachste Weg, das zu tun, ist einfach

IEnumerable<T> items = new T[]{new T("msg")};
List<string> itemsList = new List<string>();
itemsList.AddRange(items.Select(y => y.ToString()));
itemsList.Add("msg2");

Dann können Sie die Liste als IEnumerable auch, weil es IEnumerable-Schnittstelle implementiert

Sicher, man kann (Ich verlasse dein T-Geschäft beiseite):

public IEnumerable<string> tryAdd(IEnumerable<string> items)
{
    List<string> list = items.ToList();
    string obj = "";
    list.Add(obj);

    return list.Select(i => i);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top