0

私のデモコードは以下の通りです:


class Base
{

}

class SubA:Base
{
     private int propertyA;
     public int  PropertyA     
     {
          get{return propertyA}
      }
}

class SubB:Base
{
     private string propertyB;
     public string PropertyB     
     {
          get{return propertyB}
      }
}

class Program
{
     public void Action(Base obj)
     {
         //here i wanna use PropertyB if the ture obj is an instance of SubB.
         // use PropertyA if the true obj is an instance of SubA
     }
}

関数 " Action" に転送する真のオブジェクトは、SubB または SubA のインスタンスです。" " 内の( PropertyBif SubB) またはPropertyA(if ) にアクセスしたい。いくつかの基本的な OO ルールに違反していますか? このような状況に対処する最善の方法は何ですか (C# キーワードを使用したり、転送した obj をテストしたりしたくありません) 。私は今完全に混乱しています。アドバイスやヘルプをいただければ幸いです。SubAActionAsIs

4

2 に答える 2

2

as型チェックとキャストを使用することで技術的な制限を簡単に回避できますが ( isC# では既に説明したように)、これは基本的なオブジェクト指向の原則に違反しています。

Action問題は、引数として受け取ることを期待する を定義したことですBase。そのため、それが唯一の情報に依存する必要があります。タイプのオブジェクトがBase公開する必要があるデータを公開しない場合は、それを変更する必要があります。たとえば、「Property」プロパティをベースに直接追加して、ジェネリック型にするか、2 つの子を持つベース型にすることができます。1 つはint値をサポートし、もう 1 つは値をサポートしstringます。なぜ Actionデータへのアクセスが必要なのかを検討し、代わりにそのデータの使用をBaseとその子に委任すると役立つ場合があります。

于 2012-12-06T15:01:08.923 に答える
1

あなたがしたことはうまくいったと思いますが、おそらく、if (obj is SubA) {} else if (obj is SubB) {} によって obj の正確なクラス名を見つける必要があるでしょう。

経験上、void Action(Base obj) のような関数を作成する理由は、実際には Base のサブクラスに関係なく obj を処理するためです。したがって、obj を Base 型に選択するということは、関数内でサブタイプ固有の処理を行わないことを決定していることを意味します。

上記のコードでは、スーパークラス Base は SubA または SubB を Action に渡すことができるようにのみ作成されていることがわかります。Action(Base obj) では、それがSubA または SubB。SubA と SubB を Base を継承しない別のクラスにする方が理にかなっています。次に、SubA と SubB のそれぞれに対して個別の Action オーバーロードが必要です。

class Program
{
     public void Action(SubA obj)
     {
         // process exactly as SubA
     }

     public void Action(SubB obj)
     {
         // process exactly as SubB
     }
}

プログラム内の他のコードは、SubA または SubB のどちらが処理されているかを認識できるように構成する必要があります。ユーザー入力または条件に応じて、SubA または SubB をインスタンス化します。例えば:

protected void saveButton_onClick(Object sender, EventArgs e)
{
    if (User.IsInRole("Administrator"))
    {
         Action(new SubA());
    }
    else
    {
         Action(new SubB());
    }
}

適切な Action オーバーロードが呼び出されます。どのクラスをインスタンス化するかは、プログラムのロジックによって決定されます。オブジェクトの実際のタイプを「スニッフィング」する必要は、できる限り避けてください。

于 2012-12-06T15:01:59.393 に答える