2011-05-16 14 views
26

He una interfaz definida como:¿Cómo puedo convertir una lista <interface> en la lista <concrete>?

public interface MyInterface { 
    object foo { get; set; }; 
} 

y una clase que implementa la interfaz:

public class MyClass : MyInterface { 
    object foo { get; set; } 
} 

entonces crear una función que devuelve un ICollection así:

public ICollection<MyClass> Classes() { 
    List<MyClass> value; 

    List<MyInterface> list = new List<MyInterface>(
     new MyInterface[] { 
      new MyClass { 
       ID = 1 
      }, 
      new MyClass { 
       ID = 1 
      }, 
      new MyClass { 
       ID = 1 
      } 
     }); 

    value = new List<MyClass>((IEnumerable<MyClass>) list); 

    return value; 
} 

Se compilaría pero arrojaría un

No se puede convertir el objeto del tipo 'System.Collections.Generic.List 1[MyInterface]' to type 'System.Collections.Generic.IEnumerable 1 [MyClass]'.

excepción. ¿Qué estoy haciendo mal?

Respuesta

43

A List<MyInterface> no se puede convertir en un List<MyClass> en general, porque la primera lista puede contener objetos que implementan MyInterface pero que no son en realidad los objetos de tipo MyClass.

Sin embargo, dado que en el caso de que sabe cómo se construyó la lista y puede estar seguro de que sólo contiene MyClass objetos, puede hacer esto utilizando LINQ:

return list.ConvertAll(o => (MyClass)o); 
+6

Esto funcionará en .Net 2.0 o superior y no sólo como LINQ System.Collections.Generic.List <> apoya ConvertAll () directamente. –

+0

Gracias, @Ritch. Pensé que 'ConvertAll' era un método de Linq, pero no me había molestado en verificarlo. –

+0

¡Esto hizo el truco! Gracias JSBangs. – acermate433s

24

Sin embargo, un List<MyInterface> no es enfáticamente una List<MyClass> .

pienso:

interface IAnimal { } 

class Cat : IAnimal { } 
class Dog : IAnimal { } 

var list = new List<IAnimal> { new Cat(), new Dog() }; 

Entonces

var cats = (List<Cat>)list; 

Absurdo!

Además,

var cats = list.Cast<Cat>(); 

Absurdo!

Además

var cats = list.ConvertAll(x => (Cat)x); 

Absurdo!

En su lugar, se podría decir

var cats = list.OfType<Cat>(); 
+0

Ya veo. Estaba confundido porque puedes transmitir una interfaz a su clase concreta. Gracias. – acermate433s

0

encuentro AutoMapper muy útil para convertir las interfaces de clases concretas.

Cuestiones relacionadas