web-dev-qa-db-fra.com

Comment convertir une liste <interface> en une liste <concret>?

J'ai une interface définie comme:

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

et une classe qui implémente cette interface:

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

Je crée ensuite une fonction qui retourne une ICollection comme ceci:

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;
}

Il compilerait mais jetterait un

Impossible de convertir l'objet de type 'System.Collections.Generic.List1[MyInterface]' to type 'System.Collections.Generic.IEnumerable1 [MyClass]'.

exception. Qu'est-ce que je fais mal?

30
acermate433s

Un List<MyInterface> ne peut pas être converti en un List<MyClass> en général, car la première liste peut contenir des objets qui implémentent MyInterface mais qui ne sont pas réellement des objets de type MyClass.

Cependant, puisque dans votre cas, vous savez comment vous avez construit la liste et pouvez être sûr qu'elle ne contient que des objets MyClass, vous pouvez le faire avec Linq:

return list.ConvertAll(o => (MyClass)o);
48
JSBձոգչ

Mais un List<MyInterface> n'est absolument pas un List<MyClass>.

Pense:

interface IAnimal { }

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

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

Ensuite

var cats = (List<Cat>)list;

Absurde!

Également,

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

Absurde!

Plus loin

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

Absurde!

Au lieu de cela, vous pourriez dire

var cats = list.OfType<Cat>();
31
jason

Vous pouvez utiliser la méthode d'extension Cast<>:

return list.Cast<MyClass>();
1
Minh Nguyen

Je trouve Automapper très utile pour convertir des interfaces en classes concrètes. 

0
Nick Wright