Comment puis-je écrire une méthode d'extension générique pour convertir une liste à un HashSet en utilisant HashSet.AddRange ()?

StackOverflow https://stackoverflow.com/questions/1590662

Question

HashSet n'a pas une méthode AddRange, donc je veux écrire une méthode d'extension pour elle. Voilà ce que j'ai:

public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> list)
{
    foreach (var item in list)
    {
        collection.Add(item);
    }
}

J'ai une classe de base, les médias, et une classe dérivée, Photo. Voici le code que je veux travailler:

var photos = new List<Photo>();
var media = new HashSet<Media>();
media.AddRange(photos);

Cependant, le compilateur me dit qu'il ne peut pas convertir le List<Photo> à IEnumerable<Media> lorsque je tente d'utiliser AddRange(). Je suis sûr que ce soit parce que je IEnumerable<T> dans la méthode d'extension, mais comment puis-je l'écrire afin que le type est différent de celui du type à AddRange<T>?

Était-ce utile?

La solution

Une autre question-variance générique. Vous devez appeler la méthode d'extension Cast<Media> pour convertir le IEnumerable<Photo> à IEnumerable<Media> avant qu'il ne soit acceptable pour la signature de votre mise en œuvre de AddRange.

Vous pouvez déclarer

AddRange<T, U>(ICollection<T>, IEnumerable<U>) where U : T

en tant que solution pour produire la variance correcte dans la signature.

Autres conseils

En fait, HashSet<T> peut ne pas avoir une méthode de AddRange, mais il a une méthode UnionWith, qui est sémantiquement ce que vous recherchez. La différence de nom reflète le fait qu'il filtre les doublons. Il dispose également d'un constructeur qui prend un IEnumerable<T> comme paramètre, si vous voulez juste copier une collection dans un HashSet.

Dans le cas général, la réponse ci-dessus recommandant d'utiliser une contrainte générique (le « where T : U ») est correct.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top