こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C#でのあるオブジェクトの共通部分を利用したい

すみません。C#での質問をどこにすればいいかわからなかったので、こちらに投稿します。

まず、あるクラスAとBがあり、こちらのクラスは同一のスーパークラスを継承しています。

ここでAとB、双方ともに同じプロパティ(とりあえず年度とします)をもっているのですが、スーパークラスにはそのプロパティをもっていません。

ある処理でもらえるクラスはスーパークラスだとして、そこで年度を変更する場合

if (superClass is classA)
{
  classA cA = (classA)superClass;
  cA.年度 = "2007";
}
else
{
  classB cB = (classB)superClass;
  cB.年度 = "2007";
}

という感じで、

クラスがAの場合ならクラスAにキャストして変更
クラスがBの場合ならクラスBにキャストして変更

としないといけないと思います。

しかし行う処理は同じため、ここで何とか工夫してどちらのクラスでも同じコードで変更を行う事ができないでしょうか。

本来であればスーパークラス側で「年度」を定義しておくべきだと思われますが、このクラスは提供されているもので、こちらで変更できないのです。

このままだと同一のコードを大量にかかなくてはならず、困っておりますが、提供先にスーパークラス側に用意するか、あるいはもう一つスーパークラスを継承した抽象クラスを作って、それを継承して作れないかと頼んだところ、いろいろな理由があり難しいとの回答でした。

そこで受け取ったほうで何とか大量のコードを書かずに、うまくやる方法はないでしょうか?

それともやはり無理で、逐一コードをかいていくしかないでしょうか?

投稿日時 - 2008-07-30 15:09:45

QNo.4215285

すぐに回答ほしいです

質問者が選んだベストアンサー

こんにちは。

確かにもう一つスーパークラスを継承した抽象クラスを作るのが最も良い方法だと思いますが、
それが無理だとなるとある程度重複したコードを書くことは避けられませんよね。
ただ、

> まず、あるクラスAとBがあり、こちらのクラスは同一のスーパークラスを継承しています。

が可能なら間にもう一つ抽象クラスを作ることが出来ない状況が良く分かりませんね。。
インターフェースの継承であれば可能なのでしょうか?
可能であれば話しは早いのですが、クラス自体拡張することが難しいのでしょうか。


ロジックだけ抽出するなら、それ用のクラスを用意してそこを通せば良いと思いますが、
質問内容の処理のような設定が多い場合、それも無意味です。

あとは、リフレクションでプロパティに値をセットするという方法もあります。
これならば、設定するプロパティだけを考慮すればよいのでクラスに依存する必要はなくなります(メソッドもしかり)。
ただパフォーマンス面やオブジェクト指向ということを考えると、リフレクションだらけのソースは
保守性も何も無くなってしまうので、あまり良いコードとは言えないですよね。

どの方法をとっても一長一短あるので、何に重きを置くかだと思います。

投稿日時 - 2008-07-30 15:33:24

お礼

回答ありがとうございます。
やはり難しいのですね。

抽象クラスを用意出来ない理由はちょっと分からないのですが、クラス拡張する事自体がどうも難しいようです。。。
自分達で作っている部分でないだけに、手を加える事が出来ず困っていたところです。

リフレクションでプロパティにセットですか。なるほど。。
全体的に使う訳にはいかないでしょうが、内容によってはその方法も考えてみたいと思います。

ありがとうございます!

投稿日時 - 2008-07-31 15:21:17

このQ&Aは役に立ちましたか?

13人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

下記のような感じでどうでしょう?

using System;
class Program
{
  class classA
  {
    string y;
    public String 年度
    {
      get { return y; }
      set { y = value; }
    }
  }
  class classB
  {
    string y;
    public String 年度
    {
      get { return y; }
      set { y = value; }
    }
  }

  static void test(Object o)
  {
    o.GetType().GetProperty("年度").SetValue(o, "2007", null);
    
  }

  static void Main(string[] args)
  {
    classA cA = new classA();
    classB cB = new classB();
    test(cA);
    test(cB);
    System.Console.WriteLine(cA.年度);
    System.Console.WriteLine(cB.年度);
  }
}

■実行結果
2007
2007

投稿日時 - 2008-07-31 10:42:25

お礼

ありがとうございます!
この方法なら確かに同一コードでいけますね。

あとは保守性と速度の問題でしょうが……コードの内容によっては考えてみたいと思います。

ありがとうございます。

投稿日時 - 2008-07-31 15:22:47

あなたにオススメの質問