Question

Ma question comme titre ci-dessus. Par exemple,

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

mais après tout, il ne contient qu'un seul élément.

Pouvons-nous avoir une méthode comme items.Add (item) ?

comme la Liste < T >

Était-ce utile?

La solution

Vous ne pouvez pas, car IEnumerable < T > ne représente pas nécessairement une collection à laquelle des éléments peuvent être ajoutés. En fait, cela ne représente pas nécessairement une collection du tout! Par exemple:

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??

Toutefois, vous pouvez créer un objet nouvel IEnumerable (de type non spécifié), qui, une fois énuméré, fournira tous les éléments de l'ancien, plus quelques-uns des vôtres. Vous utilisez Enumerable.Concat pour cela:

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

Ceci ne changera pas l'objet tableau (vous ne pouvez pas insérer d'éléments dans les tableaux, de toute façon). Mais il va créer un nouvel objet qui listera tous les éléments du tableau, puis "Foo". De plus, ce nouvel objet suivra les modifications apportées au tableau (c’est-à-dire que chaque fois que vous l’énumérerez, vous verrez les valeurs actuelles des éléments).

Autres conseils

Le type IEnumerable < T > ne prend pas en charge de telles opérations. L’interface IEnumerable < T > a pour but de permettre à un consommateur de visualiser le contenu d’une collection. Ne pas modifier les valeurs.

Lorsque vous effectuez des opérations telles que .ToList (). Add (), vous créez une nouvelle liste < T > et ajoutez une valeur à cette liste. Il n’a aucun lien avec la liste originale.

Vous pouvez utiliser la méthode d'extension Add pour créer un nouveau IEnumerable < T > avec la valeur ajoutée.

items = items.Add("msg2");

Même dans ce cas, il ne modifiera pas l'objet IEnumerable < T > d'origine. Cela peut être vérifié en tenant une référence. Par exemple

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

Après cet ensemble d'opérations, la variable temp ne référencera toujours qu'un énumérable avec un seul élément "foo". dans l'ensemble de valeurs, tandis que les éléments référenceront un énumérable différent avec les valeurs " foo " et "bar".

MODIFIER

J'oublie constamment que la méthode d'ajout n'est pas une méthode d'extension typique sur IEnumerable < T > , car c'est l'une des premières que j'ai finalement définie. Ici c'est

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

Quelques méthodes d'extension simples et agréables sur IEnumerable et IEnumerable < T > le font pour moi:

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

Élégant (enfin, sauf pour les versions non génériques). Dommage que ces méthodes ne figurent pas dans la BCL.

Non, l'IEnumerable ne prend pas en charge l'ajout d'éléments.

Votre "alternative" est:

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

Dans .net Core, il existe une méthode Enumerable.Append qui fait exactement cela.

Le code source de la méthode est disponible sur GitHub. .... La mise en œuvre (plus sophistiquée que les suggestions des autres réponses) mérite d'être examinée :).

Pour ajouter un deuxième message, vous devez -

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

Non seulement vous ne pouvez pas ajouter des éléments comme vous le dites, mais si vous ajoutez un élément à une Liste < T > (ou à peu près toute autre collection à lecture seule), vous disposez d'un l'énumérateur est invalidé (à partir de ce moment-là, InvalidOperationException ).

Si vous agrégez les résultats d'un type de requête de données, vous pouvez utiliser la méthode d'extension Concat :

Modifier: À l’origine, j’utilisais l’extension Union dans cet exemple, ce qui n’est pas vraiment correct. Mon application l'utilise beaucoup pour s'assurer que les requêtes qui se chevauchent ne dupliquent pas les résultats.

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

Je viens juste de dire ici que, mis à part la méthode d'extension Enumerable.Concat , il semble exister une autre méthode nommée Enumerable.Append dans .NET Core 1.1.1. . Ce dernier vous permet de concaténer un seul élément à une séquence existante. Donc, la réponse d'Aamol peut aussi être écrite comme

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

Néanmoins, veuillez noter que cette fonction ne changera pas la séquence d'entrée, elle renverra simplement un wrapper qui associe la séquence donnée et l'élément ajouté.

D'autres ont déjà fourni de bonnes explications sur les raisons pour lesquelles vous ne pouvez pas (et ne devriez pas!) pouvoir ajouter des éléments à un IEnumerable . J'ajouterai seulement que si vous souhaitez continuer à coder sur une interface qui représente une collection et souhaitez utiliser une méthode add, vous devez coder pour ICollection ou IList . En bonanza ajouté, ces interfaces implémentent IEnumerable .

vous pouvez le faire.

//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;

Le moyen le plus simple de le faire est tout simplement

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

Ensuite, vous pouvez renvoyer la liste en tant que IEnumerable également car il implémente l'interface IEnumerable

Bien sûr, vous pouvez (je laisse votre entreprise T de côté):

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

    return list.Select(i => i);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top