web-dev-qa-db-ja.com

List <interface>をList <concrete>に変換するにはどうすればよいですか?

私は次のように定義されたインターフェースを持っています:

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

そしてそのインターフェースを実装するクラス:

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

次に、次のようにICollectionを返す関数を作成します。

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

コンパイルされますが、スローされます

タイプ「System.Collections.Generic.List1[MyInterface]' to type 'System.Collections.Generic.IEnumerable1 [MyClass]」のオブジェクトをキャストできません。

例外。何が悪いのですか?

38
acermate433s

最初のリストにはMyInterfaceを実装しているが、実際にはMyClassタイプのオブジェクトではないオブジェクトが含まれている可能性があるため、List<MyInterface>は一般にList<MyClass>に変換できません。

ただし、あなたの場合はリストの作成方法がわかっており、リストにMyClassオブジェクトのみが含まれていることを確認できるため、Linqを使用してこれを行うことができます。

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

ただし、List<MyInterface>List<MyClass>ではありません。

考える:

interface IAnimal { }

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

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

その後

var cats = (List<Cat>)list;

不条理!

また、

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

不条理!

さらに

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

不条理!

代わりに、あなたは言うことができます

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

Cast<>拡張メソッド:

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

以下のようにキャストを使用します。

list.Cast<T>().ToList()
1
cahit beyaz

Automapperは、インターフェースを具象クラスに変換するのに非常に便利です。

0
Nick Wright