¿Cómo puedo escribir un método de extensión genérica para convertir una lista en un HashSet usando HashSet.AddRange ()?
-
22-09-2019 - |
Pregunta
HashSet no tiene un método AddRange, por lo que quiero escribir un método de extensión por ello. Esto es lo que tengo:
public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> list)
{
foreach (var item in list)
{
collection.Add(item);
}
}
Tengo una clase base, los medios de comunicación, y una clase derivada, Foto. Este es el código que quiero trabajo:
var photos = new List<Photo>();
var media = new HashSet<Media>();
media.AddRange(photos);
Sin embargo, el compilador me está diciendo que no se puede convertir el List<Photo>
a IEnumerable<Media>
cuando trato de usar AddRange()
. Estoy bastante seguro de que esto es porque tengo IEnumerable<T>
en el método de extensión, pero ¿cómo lo escribo para que el tipo es diferente que el tipo de AddRange<T>
?
Solución
Sin embargo, otro tema genérico-varianza. Tendrá que llamar al método de extensión Cast<Media>
para convertir el IEnumerable<Photo>
a IEnumerable<Media>
antes de que sea aceptable para la firma de su aplicación AddRange
.
Como alternativa, se puede declarar
AddRange<T, U>(ICollection<T>, IEnumerable<U>) where U : T
como una solución para producir la varianza correcta en la firma.
Otros consejos
En realidad, HashSet<T>
puede no tener un método AddRange
, pero tiene un método UnionWith
, que es semánticamente lo que busca. La diferencia en el nombre refleja el hecho de que filtra los duplicados. También tiene un constructor que toma un IEnumerable<T>
como un parámetro, si lo que desea es copiar una colección en un HashSet
.
En el caso general, la respuesta anterior recomendando utilizar una restricción genérico ( "where T : U
") es correcta.