###質問内容
C#のダウンキャストについてお尋ねします。
クラスのキャストは、以下の方法で出来ました。
C#
1Base b = new AnotherClass(); //ok 2AnotherClass a = (AnotherClass)b; //ok
しかし、List<T>で同じようなことをすると、
型が違うと言われエラーになります。
どのようにしたら、実現できるのでしょうか。
*環境*
◎WPF(C#) .net Frame Work 4.5
◎visual studio Community
◎windows7 64bit
仕掛中のソース
C#
1List<Base> b = new List<AnotherClass>(); //エラー 2List<AnotherClass> a = (List<AnotherClass>)b; //エラー
どうかご教示ねがいます。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
ベストアンサー
List<> は値の入力、出力の両方ができるため変換ができないのです。
しかし、以下のようなコードはエラーにはなりません。(共変)
cs
1IReadOnlyList<Base> b = new List<AnotherClass>();
追記
下のパターンであれば、問題ないと思います。
cs
1IReadOnlyList<Base> b = new List<AnotherClass>(); 2List<AnotherClass> c = (List<AnotherClass>)b;
多分もう気づいてると思いますが、挙げられた失敗パターンは全て Base
型インスタンスを無理やり AnotherClass
変えようとしています。
追記2
ちなみに、もし既にある List<Base>
を List<AnotherClass>
に変えたい場合はこうすればできます。
cs
1public class Base { } 2 3public class AnotherClass : Base 4{ 5 public AnotherClass(Base b) { } 6} 7 8var baseList = new List<Base>(); 9var drivedList = baseList 10 .Select(x => new AnotherClass(x)) 11 .ToList();
投稿2018/11/08 23:09
編集2018/11/09 09:38総合スコア449
0
こんにちは。
既に回答は出ているので蛇足ですが。
List<Base>
をList<Derived>
にキャストできない理由を考えてみましょう。
まずは以下のように、
csharp
1List<Base> baseList = derivedList.Cast<Base>().ToList();
Derived
のリストから作ったBase
のリストがあるとします。当たり前ですけど、これは「Base
のリスト」なんです。ということは、
csharp
1baseList.Add(new Base()); // baseListにはBaseが入ります!
このbaseList
をDerived
のリストにキャストすると、
csharp
1List<Derived> newDerivedlist = (List<Derived>)baseList; // baseListの中にはDerivedじゃないオブジェクトが居る!
どうしてキャストが許可されないのかこれで分かると思います。
投稿2018/11/09 06:00
総合スコア4103
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
回答欄を見ていて思ったのですが、
DB.MT_Report.ToList(); //データ読みこみ
として生成されるリストの各要素がそもそもMT_ReportPlus型ではないのではないでしょうか?
もともとMT_Reportとして生成されたインスタンスをMT_ReportPlusにキャストは出来ないかと思います。
型を調べてみてはいかがでしょうか。
投稿2018/11/09 05:21
総合スコア8356
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/09 06:38
2018/11/09 07:45
2018/11/09 09:06
2018/11/09 09:30
0
List<AnotherClass>とList<Base>は全く別の型なのでキャストすることはできません。
※間違いでした。追記をご覧下さい。
対処として、
Enumerable.Cast
があります。
Linqをusingして
c#
1using System.Linq;
c#
1List<Base> b = new List<AnotherClass>().Cast<Base>().ToList();
このようにすると可能です。
内部的な処理としてはこんな感じの事をしています。
c#
1List<Base> Cast(List<AnotherClass> list) 2{ 3 List<Base> res = new List<Base>(); 4 foreach(var e in list) 5 { 6 res.Add(e as AnotherClass); 7 } 8 return res; 9}
※追記
List<AnotherClass>とList<Base>は全く別の型なのでキャストすることはできません。
と書きましたがgaya-Kさんの言う通りジェネリックの共変性・反変性による物でした。
※テストコードを追加
C#
1using System; 2using System.Linq; 3using System.Collections.Generic; 4class MT_Report { } 5class MT_ReportPlus : MT_Report { } 6class Class 7{ 8 static void Main() 9 { 10 List<MT_Report> baseList = new List<MT_ReportPlus>().Cast<MT_Report>().ToList(); 11 List<MT_ReportPlus> plusList = baseList.Cast<MT_ReportPlus>().ToList(); 12 } 13}
投稿2018/11/08 21:17
編集2018/11/09 05:31総合スコア90
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/09 05:01
2018/11/09 05:31
2018/11/09 07:14
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/09 04:51
2018/11/09 09:33
2018/11/09 10:00
2018/11/09 10:03
2018/11/09 10:14
2018/11/09 10:20 編集
2018/11/09 10:53