91 votes

Comment ajouter une série d'éléments à une IList ?

Il n'y a pas AddRange() méthode pour IList<T> .

Comment ajouter une liste d'éléments à un fichier IList<T> sans itérer à travers les éléments et en utilisant la fonction Add() méthode ?

91voto

BlackjacketMack Points 1057

Si vous regardez le Code source C# pour List<T> Je pense que List<T>.AddRange() a des optimisations qu'une simple boucle n'aborde pas. Ainsi, une méthode d'extension devrait simplement vérifier si l'IList<T> est une List<T>, et si c'est le cas, utiliser sa méthode native AddRange().

En fouillant dans le code source, on voit que les gens de .NET font des choses similaires dans leurs propres extensions LINQ pour des choses comme .ToList() (s'il s'agit d'une liste, il faut la couler... sinon il faut la créer).

public static class IListExtension
{
    public static void AddRange<T>(this IList<T> list, IEnumerable<T> items)
    {
        if (list == null) throw new ArgumentNullException(nameof(list));
        if (items == null) throw new ArgumentNullException(nameof(items));

        if (list is List<T> asList)
        {
            asList.AddRange(items);
        }
        else
        {
            foreach (var item in items)
            {
                list.Add(item);
            }
        }
    }
}

72voto

Oded Points 271275

AddRange est défini sur List<T> et non l'interface.

Vous pouvez déclarer la variable comme List<T> au lieu de IList<T> ou l'envoyer à List<T> afin d'avoir accès à AddRange .

((List<myType>)myIList).AddRange(anotherList);

Ce n'est pas une bonne pratique (voir les commentaires ci-dessous), car une IList<T> pourrait pas être un List<T> mais un autre type qui implémente l'interface et peut très bien ne pas avoir de AddRange Dans ce cas, vous ne le découvrirez que lorsque votre code lèvera une exception au moment de l'exécution.

Ainsi, à moins que vous ne soyez certain que le type est bien une List<T> vous ne devriez pas essayer d'utiliser AddRange .

Une façon de le faire est de tester le type avec la fonction est o comme (depuis C# 7).

if(myIList is List<T>)
{
   // can cast and AddRange
}
else
{
   // iterate with Add
}

25voto

cocre8or Points 1298

Vous pourriez faire quelque chose comme ça :

IList<string> oIList1 = new List<string>{"1","2","3"};
IList<string> oIList2 = new List<string>{"4","5","6"};
IList<string> oIList3 = oIList1.Concat(oIList2).ToList();

Donc, en gros, vous utiliseriez le Concat() l'extension et ToList() pour obtenir une fonctionnalité similaire à celle de AddRange() .

Source :

10voto

bashis Points 597

Vous pouvez également écrire une méthode d'extension comme ceci :

internal static class EnumerableHelpers
{
    public static void AddRange<T>(this IList<T> collection, IEnumerable<T> items)
    {
        foreach (var item in items)
        {
            collection.Add(item);
        }
    }
}

Utilisation :

IList<int> collection = new MyCustomList(); //Or any other IList except for a fixed-size collection like an array
var items = new[] {1, 4, 5, 6, 7};
collection.AddRange(items);

Ce qui revient à itérer sur des éléments, mais vous n'avez pas besoin d'écrire l'itération ou le cast à chaque fois que vous l'appelez.

4voto

RedRain Points 53

Une autre réponse utilise LINQ, à condition que la chose que vous ajoutez est un List<T> ou vous pouvez appeler ToList() sur elle :

IEnumerable<string> toAdd = new string[] {"a", "b", "c"};
IList<string> target = new List<string>();

toAdd.ToList().ForEach(target.Add);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X