5

実行時に、、またはoの 3 つのタイプのいずれかであることが保証されているオブジェクトがあります。これらはすべて、共通のインターフェイスを実装しています。を制御できますが、 、、またはは制御できません。(したがって、空のマーカー インターフェイスを使用するか、インターフェイスを使用して型の類似性を利用することはできますが、新しいメソッドを追加したり、型の既存のメソッドを変更したりすることはできません。)ABCIIABC

また、一連のメソッドMethodAMethodB、および がありMethodCます。のランタイム タイプoが検索され、これらのメソッドのパラメータとして使用されます。

public void MethodA(A a) { ... }
public void MethodB(B b) { ... }
public void MethodC(C c) { ... }

この戦略を使用すると、現時点では、oどのメソッドを呼び出す必要があるかを判断するために、の型に対してチェックを実行する必要があります。代わりに、単純に 3 つのオーバーロードされたメソッドを使用したいと思います。

public void Method(A a) { ... } // these are all overloads of each other
public void Method(B b) { ... }
public void Method(C c) { ... }

今では、自分で手動でディスパッチする代わりに、C# にディスパッチを任せています。これはできますか?もちろん、素朴で簡単なアプローチは機能しません。

メソッド 'Method(object)' を解決できません。候補者は次のとおりです。

  • void メソッド(A)
  • void メソッド(B)
  • void メソッド(C)
4

5 に答える 5

7

これをリファクタリングできる場合は、メソッドをインターフェイスに移動し、各クラスに実装を持たせます。

I i = o as I;
i.Method();
于 2010-05-12T11:56:53.857 に答える
5

このようなものはどうですか?

private Dictionary<Type, Action<I>> _mapping = new Dictionary<Type, Action<I>>
{ 
  { typeof(A), i => MethodA(i as A)},
  { typeof(B), i => MethodB(i as B)},
  { typeof(C), i => MethodC(i as C)},
};

private void ExecuteBasedOnType(object value)
{
    if(_mapping.ContainsKey(value.GetType()))
       _mapping(value.GetType())(value as I);
}
于 2010-05-12T11:56:01.660 に答える
0

これがあなたのシナリオで機能するかどうかは100%わかりませんが、部分クラスを使用できるようです:

public interface IMethodCallable
{
    public void Method();
}

public partial class A : IMethodCallable
{
    public void Method()
    {
        ....
    }
}

次に、使用法について:

object o = getObject(); // we know this is A, B or C
((IMethodCallable)o).Method();
于 2010-05-12T12:10:01.683 に答える
0

おそらく、O はタイプ/インターフェース I として宣言され、ab または c としてインスタンス化されます。それを行う方法は、タイプ I のパラメーターを受け取る単一のパブリック メソッドを用意し、そのメソッド内でロジックを実行することです。たとえば、プライベート メソッド AB または C を呼び出します。

編集した投稿を読んで、o はオブジェクト型です。オブジェクトについて理解するときは、ac# 型であるだけでなく、クラスのインスタンスの一般的な oop 用語であるため、明確にすることを忘れないでください。

i ではなくオブジェクトとして宣言するのはなぜですか。後で別のものになる可能性があります。

その場合、オーバーロードされたメソッドを使用するには、メソッドを呼び出す前にボックス化を解除する必要があります。例えば

if (o.GetType() == typeof(a))
{
   oa = (a)o;
   Method(oa);
}
else if(o.GetType() == typeof(b))
{
    ...
}

等。

あるいは、メソッドがタイプ i のパラメーターを取るようにした場合は、次のようにすることができます。

i oi = (i)o;
Method(oi);

ただし、パブリック メソッド内で最初の例のようなことを行う必要があります。

于 2010-05-12T11:54:47.157 に答える
0

A、B、C の 3 つのクラスがインターフェイス I を実装している場合は、何もしないでください。適切な方法を選択するのはランタイムです。

A a = new A();
class.Method(a); // will calll Method(A a)

B b = new B();
class.Method(b); // will call Method(B b)
于 2010-05-12T11:51:45.180 に答える