0

毎日の勤務時間中に、1 つの問題に遭遇しました。

仮定する:

  1. オブジェクトAがあり、それはObjectタイプです
  2. たぶんタイプまたはBタイプC
  3. タイプBC同じ名前のメソッドを持っていますGetSomething()
  4. B両方の実装が同じインターフェースであるかどうかはわかりませんC(つまり、それらの間の関係がわからないことを意味します)
  5. typeBCinherit fromObjectは何の助けにもなりません。同じメソッド名を除けば、型Bと型については何も知りません。C

GetSomething問題は、型に関係なく、Aから呼び出したいということです。

//Object A maybe type B or C
//both B and C can call method
//but we just don't know type of A
var result=A.GetSomething();

このシナリオに遭遇した場合、あなたはどうしますか?

4

5 に答える 5

3

それは抽象メソッドを求めているようです

public abstract class A {
   protected abstract object GetSomething();
}

次に、各派生クラスで GetSomething() を実装する必要があります。

public class B : A {
   protected override object GetSomeTHing(){
      //implementation goes here
   }
}

GetSomething()その後、スーパークラスの実装のどこでも自由に呼び出すことができます( A)

スーパークラスの実装内から呼び出す方法を探しているのではなく、他の場所から呼び出す方法を探している場合は、基本的に3つのオプションがあります

  • スーパークラスの実装を変更して、メソッドの (潜在的な抽象) 定義を含めます。
  • 動的型付けを使用する
  • 反射を使用する

前者は基本的に上記の例と同じです( のpublic代わりにアクセス修飾子を作るだけですprotected

2 番目と 3 番目のオプションには、どちらも同じ欠点があります。それらはコンパイル時に型付けされていないため、開発中にコンパイル時エラーではなく実行時エラーが発生することがあります。ただし、テストのカバレッジが高い場合は、それほど問題にはなりません。

リフレクション バージョンよりも読み書きが簡単なので、動的型付けを使用することをお勧めします。int を返すと仮定するとGetSomething、次のようになります。

int 結果 = ((動的)A).GetSomething();

結果を暗黙的に型指定するのではなく、明示的に型指定するように変更しましたdynamic。戻り値の型がわかっている場合GetSomethingは、事前にコンパイラに伝える方がよいでしょう

于 2013-06-28T11:48:17.460 に答える
1
  • タイプ B と C には同じ名前のメソッド GetSomething() があります
  • B と C の両方が同じインターフェースを実装しているかどうかはわかりません

わかりませんが、変更できますか?最も論理的な解決策は、インターフェイスで「何か」の動作を記述することです。

interface IHasSomething
{
    Something GetSomething();
}

そして、それをクラス B と C に適用します。

B および C インスタンスが として宣言されている場合object、それらがこのインターフェイスを実装しているかどうかをテストできます。

var something = obj as IHasSomething
if (something != null)
{
    var youWereLookingFor = something.GetSomething();
}

または、リフレクションを使用してみることができます。これは、優れた OO 設計とは対照的に、常に最後の手段である必要があります (パラメーターやオーバーロードを追加したり、別のメソッドを呼び出したり、別の戻り値の型を使用したりしたい場合など)。

于 2013-06-28T11:55:09.603 に答える
0

メソッドがない場合Aは、設計が悪く、OOP の原則に反するため、それを行うことを考えるべきではありません。ただし、絶対にそのようにする必要がある場合は、リフレクションを使用してみてください。

MethodInfo methodInfo = this.GetType().GetMethod("GetSomething", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
if(methodInfo != null)
   result = methodInfo.Invoke(this, new object[] {});

ただし、抽象クラスを使用するか、クラスでデフォルトを使用することを強くお勧めしGetSomething()ますA...

于 2013-06-28T11:55:00.857 に答える