être - méthode d'extension c#




AddRange à une collection (4)

Un collègue m'a demandé aujourd'hui comment ajouter une gamme à une collection. Il a une classe qui hérite de Collection<T> . Il existe une propriété get-only de ce type qui contient déjà certains éléments. Il veut ajouter les éléments d'une autre collection à la collection de propriétés. Comment peut-il le faire d'une manière amicale C # 3? (Notez la contrainte sur la propriété get-only, qui empêche les solutions de faire Union et de réaffecter.)

Bien sûr, un foreach avec la propriété. Ajouter va fonctionner. Mais un AddRange de List<T> serait beaucoup plus élégant.

Il est assez facile d'écrire une méthode d'extension:

public static class CollectionHelpers
{
    public static void AddRange<T>(this ICollection<T> destination,
                                   IEnumerable<T> source)
    {
        foreach (T item in source)
        {
            destination.Add(item);
        }
    }
}

Mais j'ai l'impression de réinventer la roue. Je n'ai rien trouvé de similaire dans System.Linq ou morelinq .

Mauvais design? Appelez simplement Ajouter? Manquer l'évidence?


Depuis .NET4.5 si vous voulez une ligne, vous pouvez utiliser System.Collections.Generic ForEach.

source.ForEach(o => destination.Add(o));

ou même plus court comme

source.ForEach(destination.Add);

Les performances sont les mêmes que pour chaque boucle (sucre syntaxique).

N'essayez pas non plus de l' assigner comme

var x = source.ForEach(destination.Add) 

cause ForEach est vide.


Essayez d'effectuer la diffusion dans List dans la méthode d'extension avant d'exécuter la boucle. De cette façon, vous pouvez profiter des performances de List.AddRange.

public static void AddRange<T>(this ICollection<T> destination,
                               IEnumerable<T> source)
{
    List<T> list = destination as List<T>;

    if (list != null)
    {
        list.AddRange(source);
    }
    else
    {
        foreach (T item in source)
        {
            destination.Add(item);
        }
    }
}

N'oubliez pas que chaque Add vérifiera la capacité de la collection et la redimensionnera si nécessaire (plus lent). Avec AddRange , la collection définira la capacité, puis ajoutera les éléments (plus rapidement). Cette méthode d'extension sera extrêmement lente, mais fonctionnera.


Non, cela semble parfaitement raisonnable. Il y a une List<T>. AddRange() méthode AddRange() ne fait que cela, mais nécessite que votre collection soit une List<T> concrète List<T> .





extension-methods