型 'System.Collections.Generic.List<派生>' を 'System.Collections.Generic.List<基底>' に暗黙的に変換できません
基底クラスと派生クラスがあるとき、基底クラスのオブジェクトbへ派生クラスのオブジェクトdを代入することはできる。つまり「b=d;」はOKなのだが、しかしListを代入しようとするとエラーが起きるわけです。
つまり、「List<基底> bList」と「List<派生> dList」の2つのリストがあるとき、「bList = dList」はビルドエラーになる。
これ、できないのか、初めて知ったような気がする。
マイクロソフトのジェネリックの説明を読んでみると、それらしいことがさらっと書いてあった。ジェネリック クラス (C# プログラミング ガイド)の末尾あたり。
調べていくと、ジェネリックの共変性と反変性 という話につながるらしいが、よくわからない。Listは中身を変更できるから、「ListB = ListD」 したあとに、「ListD = (ListD) ListB」 できる保証がないからダメということなのだろうか。
あと、IEnumerable はリストの中身を参照するだけなので(列挙子)、これを使えば代入可能になるみたい。AsEnumerable メソッドはこう云う感じで使えるのか。
つまり、「List<基底> bList」と「List<派生> dList」の2つのリストがあるとき、「bList = dList」はビルドエラーになる。
これ、できないのか、初めて知ったような気がする。
マイクロソフトのジェネリックの説明を読んでみると、それらしいことがさらっと書いてあった。ジェネリック クラス (C# プログラミング ガイド)の末尾あたり。
ジェネリック クラスは変化しません。 言い換えると、入力パラメーターが List<BaseClass> を指定するとき、List<DerivedClass> を指定するとコンパイル時エラーが表示されます。これはメソッドのパラメータに渡す場合の説明だけど、代入も同じようにエラーになるということか、、、知らなかった。
調べていくと、ジェネリックの共変性と反変性 という話につながるらしいが、よくわからない。Listは中身を変更できるから、「ListB = ListD」 したあとに、「ListD = (ListD) ListB」 できる保証がないからダメということなのだろうか。
とりあえずの解決策
リストをキャストすればエラーは出なくなる。var BList = DList.ToList<mm基底>();ちょっと無理やり感がありますな。
あと、IEnumerable はリストの中身を参照するだけなので(列挙子)、これを使えば代入可能になるみたい。AsEnumerable メソッドはこう云う感じで使えるのか。
IEnumerable<mm基底> BIEnum; IEnumerable<mm派生> DIEnum = DList.AsEnumerable(); BIEnum = DIEnum;型をパラメータとして渡せるジェネリックはうまいアイデアなのだけど、継承が絡んでくるとややこしいところが現れて来て、なかなか難しいものだなあ。
コメント
コメントを投稿