私は次のように定義されたインターフェースを持っています:
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.List
1[MyInterface]' to type 'System.Collections.Generic.IEnumerable
1 [MyClass]」のオブジェクトをキャストできません。
例外。何が悪いのですか?
最初のリストにはMyInterface
を実装しているが、実際にはMyClass
タイプのオブジェクトではないオブジェクトが含まれている可能性があるため、List<MyInterface>
は一般にList<MyClass>
に変換できません。
ただし、あなたの場合はリストの作成方法がわかっており、リストにMyClass
オブジェクトのみが含まれていることを確認できるため、Linqを使用してこれを行うことができます。
return list.ConvertAll(o => (MyClass)o);
ただし、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>();
Cast<>
拡張メソッド:
return list.Cast<MyClass>();
以下のようにキャストを使用します。
list.Cast<T>().ToList()
Automapperは、インターフェースを具象クラスに変換するのに非常に便利です。