Lista de conversión<T> a lista<Interfaz>

Resuelto Andrew Kalashnikov asked hace 12 años • 10 respuestas
public interface IDic
{
    int Id { get; set; }
    string Name { get; set; }
}
public class Client : IDic
{

}

¿Cómo puedo List<Client>transmitir List<IDic>?

Andrew Kalashnikov avatar Jan 19 '12 18:01 Andrew Kalashnikov
Aceptado

No puede transmitirlo (preservando la identidad de referencia); eso no sería seguro. Por ejemplo:

public interface IFruit {}

public class Apple : IFruit {}
public class Banana : IFruit {}

...

List<Apple> apples = new List<Apple>();
List<IFruit> fruit = apples; // Fortunately not allowed
fruit.Add(new Banana());

// Eek - it's a banana!
Apple apple = apples[0];

Ahora puede convertir a List<Apple>en IEnumerable<IFruit>.NET 4/C# 4 debido a la covarianza, pero si desea a, List<IFruit>tendrá que crear una nueva lista. Por ejemplo:

// In .NET 4, using the covariance of IEnumerable<T>
List<IFruit> fruit = apples.ToList<IFruit>();

// In .NET 3.5
List<IFruit> fruit = apples.Cast<IFruit>().ToList();

Pero esto no es lo mismo que emitir la lista original, porque ahora hay dos listas separadas . Esto es seguro, pero debe comprender que los cambios realizados en una lista no se verán en la otra lista. ( Por supuesto, se verán modificaciones a los objetos a los que se refieren las listas.)

Jon Skeet avatar Jan 19 '2012 11:01 Jon Skeet

Yo también tuve este problema y después de leer la respuesta de Jon Skeet modifiqué mi código de usar List<T>a usar IEnumerable<T>. Aunque esto no responde a la pregunta original del OP sobre ¿Cómo puedo transmitir contenido List<Client>?,List<IDic> evita la necesidad de hacerlo y, por lo tanto, puede ser útil para otras personas que encuentren este problema. Por supuesto, esto supone que el código que requiere el uso List<IDic>está bajo su control.

P.ej:

public void ProcessIDic(IEnumerable<IDic> sequence)
{
   // Implementation
}

En lugar de:

public void ProcessIDic(List<IDic> list)
{
   // Implementation
}
Ɖiamond ǤeezeƦ avatar Jan 27 '2016 11:01 Ɖiamond ǤeezeƦ

Un iterador Cast y .ToList():

List<IDic> casted = input.Cast<IDic>().ToList()hará el truco.

Originalmente dije que la covarianza funcionaría, pero como Jon señaló acertadamente; ¡No, no lo hará!

Y originalmente también dejé estúpidamente la ToList()llamada.

Andras Zoltan avatar Jan 19 '2012 11:01 Andras Zoltan

Si puedes usar LINQ, entonces puedes hacer esto...

List<Client> clientList = new List<Client>();
List<IDic> list = clientList.Select(c => (IDic)c).ToList();
musefan avatar Jan 19 '2012 11:01 musefan