C# で Generics を親クラスで受け取れない
◆ Linq の Cast する
public class A
{
}
public class B : A
{
}
{
}
public class B : A
{
}
だと
A a = new A();
A b = new B();
A b = new B();
こういう風に親のクラス A の型の変数に B のインスタンスを代入できます
これのおかげで Generic にするのがめんどうなときにとりあえず object 型を引数や返り値にしてどの型でもあつかえるようにできます
ですが List<A> と List<B> のような場合はエラーになります
List<A> a = new List<A>{ new A() };
List<A> b = new List<B>{ new B() }; // error
error CS0029: Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List'
List<A> b = new List<B>{ new B() }; // error
error CS0029: Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List'
ベースのクラスのプロパティに List<object> 型を指定しておいて子クラスで実際の型にキャストしてってやりたいことが多いのでちょっと使いづらいです
単純なのなら Generics でいいのですけど 型が5つも6つもかかないといけなくなると もう object のほうがすっきりしていていいですし
どうにかできないのかなーと思って色々やってると意外と単純で .Cast<A>() をすればおっけいでした
List<A> a = new List<A>{ new A() };
List<A> b = new List<B>{ new B() }.Cast<A>().ToList();
Console.WriteLine(b.First().GetType().ToString());
// B
List<A> b = new List<B>{ new B() }.Cast<A>().ToList();
Console.WriteLine(b.First().GetType().ToString());
// B
キャストで A 型にしていますが 実際の型をみるとちゃんと B なので 使うところで B 型にキャストすれば問題なく使えます
(A 型 B 型 が血液型みたいにみえてきた)
こういう手間がいるのは静的型付け言語の使いづらいとこですね