忍者ブログ

サバイバル系FPSを作るブログ

ゲーム作成状況を載せて行きますよ。 いつ完成する事やら・・・

c# 派生クラスに基底クラスをぶち込む「ダウンキャスト」について。

継承したクラス、
派生クラスの変数にどうしても基底クラスを
代入したいそんな時皆さんはどうしていますか?

ちなみに皆様ご存知違う型への変換を「キャスト」
と呼びますよね。実はその中に細分化されてまして
アップキャストとダウンキャストというものがあります。


アップキャストとは、
派生クラスを基底クラスに入れる事です。
例えば、

   //基底クラス
   class Base { }   
   //派生クラス
   class  Derived : Base { }

   

   //基底クラス型の「b」
   Base b;
   //派生クラス型の「d」
   Derived d;


   //インスタンス生成
   b = new Base();
   
   //派生クラス「b」を基底クラス「d」に代入可能。
   d = b ;


これがアップキャストだそうです。
派生を基底に代入する事は何の問題もなく代入可能
のようなのです。キャストすらする必要も無いという。
しかしこの逆の基底を派生に代入する、というのが少し
ばかり注意みたいで、これを「ダウンキャスト」と言う
ようです。

ではまったく同じ事をして見ましょう。


  //基底クラス
   class Base { }   
   //派生クラス
   class  Derived Base { }

   

   //基底クラス型の「b」
   Base b;
   //派生クラス型の「d」
   Derived d;

 
   //インスタンスの生成
   d= new  Derived();

   //キャストしてもエラーになる
   b = (Base)d;


これはエラーになってしまうんですね。
一見派生のほうが基底のクラスよりメンバが
同じかそれ以上あるので、基底にあるメンバ
のみに代入してくれそうな気はしますが残念
ながら基底クラス側「b」が「d?そんな奴
しらないよ!」と拒絶するのです。

キャストとはどうやら型を変換するだけであり、

中身自体の値が消えるわけではない

と言う点に注意。


ではどうすればダウンキャストできるのでしょうか?
キャストでだめなら一体どうすれば・・・意外にダウン
キャストの情報はそれほど多くないのです。

大体が良く分からない(理解できる脳を持ち合わせていない)
中、これは!というものを見つけました。

重要なタイミングはどうやらインスタンス化にあるようです!!
最初のBase型に同じ型でnewするのではなく、


//ここが重要!
b = new Derived ();

d = (Derived )b;

派生型を入れてやる事がミソなんだそうです。
Base型なのに派生型のDerivedをnewするなんて
c++から来た私には異様に見えますw

まぁ、なぜ問題なくできるのかと言うのは正直
説明できません。理解するには今一度、宣言とは、
C#のnewとは、キャストとはどんなものかを
掘り下げて勉強する必要が出てきそうですね・・・


PR