<前提>
疑問点をどのような言葉で表現してよいかわからず、タイトルと内容が合っていないかもしれません。
また、質問の書き方もおかしいかもしれません。
<やりたいこと>
複数の子クラスのいずれか1つのオブジェクトを保持するため親クラスオブジェクトを用意する。
親クラスオブジェクトのメソッドを使うときは必ず子クラスにキャストしてから使う。
<質問>(2つあります)
質問1:やりたいことを実現するため、下記コードを考えましたが問題ないでしょうか。
C#
1 public partial class Form1 : Form 2 { 3 int childType = 1; 4 cParent cp; 5 6 public Form1() 7 { 8 InitializeComponent(); 9 } 10 11 private void button1_Click(object sender, EventArgs e) 12 { 13 if (childType == 1) 14 { 15 cp = new cChild1(); // ① 16 int c1 = ((cChild1)cp).GetC(); // ②-1 17 ((cChild1)cp).Dispose(); // ②-2 18 } 19 else 20 { 21 cp = new cChild2(); 22 int c2 = ((cChild2)cp).GetC(); 23 ((cChild2)cp).Dispose(); 24 } 25 } 26 } 27 28 public class cParent 29 { 30 } 31 32 public class cChild1 : cParent, IDisposable 33 { 34 private int c1 = 10; 35 36 public int GetC() 37 { 38 return c1; 39 } 40 41 public void Dispose() 42 { 43 // ここでは何もしないが、実際は正しく実装されているものとする。 44 } 45 46 } 47 48 public class cChild2 : cParent, IDisposable 49 { 50 private int c2 = 20; 51 52 public int GetC() 53 { 54 return c2; 55 } 56 57 public void Dispose() 58 { 59 // ここでは何もしないが、実際は正しく実装されているものとする。 60 } 61 }
質問2:button1_Clickではif文でキャスト判断していますが、できれば型自体を保持しておき、
型がcTypeに入っているとして下記のようなコードでif文を無くすことはできないでしょうか。
C#
1cp = new cType(); // ① 2int c1 = ((cType)cp).GetC(); // ②-1 3((cType)cp).Dispose(); // ②-2
本当に親クラスにGetCなどの定義は無いんですか? ライブラリ作成者がまともな思考をしていれば存在してそうなものですが。
はい、ありません。今回は質問用にコードを書きましたが、作法に合わないことをしていたら申し訳ありません。
では、実際のコードでcp.GetC()に相当するコード書いたらコンパイルエラーになったんですね?
いえ、コンパイルエラーにはなっていません。実行もできます。
ということは親クラスにGetC() (相当)が存在していませんか?
はい、再度確認しましたが、存在していません。
cParent型の変数cpに対して、cp.GetC()と書いてエラーにならないということは、C#の仕様上、cParent型は何らかの形でGetC()を持っているはずです。実際のコードの親クラスに更に親が存在していたり、親がpartialであったり、cChildXのGetCにあたるメソッドの定義にoverrideとかついてません?
はい、それは理解できます。読み返していて思いましたが、10:36の記載を私が誤解したかもしれません。「cp.GetC()」というコードはご指摘の通りコンパイルエラーになります。しかし、「 ((cChild1)cp).GetC()」というコードはコンパイルエラーになりません。私はこれを「cp.GetC()に相当するコード」と解釈しておりました。
回答5件
あなたの回答
tips
プレビュー