9

私は次のことをしようとしています:

public abstract BaseClass {

  public virtual void ReceiveEvent(Event evt)
    {
        ProcessEvent(evt as dynamic);
    }

    private void ProcessEvent(object evt)
    { 
        LogManager.Log(@"Received an event that is not being processed! 
                        Dispatch fallback");
    }
}

public DerivedClass: BaseClass {

    private void ProcessEvent(SpecificEvent evt)
    { 
        LogManager.Log("Processing Event");
    }
}

SpecificEvents は、派生クラスのフォールバック メソッドではなく、フォールバック メソッドにヒットします。私は常に同じクラス内で動的ディスパッチを使用していますが、非常に便利でクリーンです。上記の例に示されているように、派生クラスでは機能しませんか?

編集: 答えには混乱があるようです。基本的に、私は常に次のデザインを使用しています。

public class SomeClass{

    public void DoSomethingDispatcher(SomeObject obj)
    {
        ProcessObject(obj as dynamic);
    }

    private void DoSomething(SomeObjectType1 obj)
    { 

    }

    private void DoSomething(SomeObjectType2 obj)
    { 

    }

    private void DoSomething(SomeObjectType3 obj)
    { 

    }

    private void DoSomething(object obj) //fallback
    { 

    }
}

事前に正確なタイプがわからず、大きな switch ステートメントを使用したくない場合に最適です。基本クラスがフォールバックメソッドを保持し、派生クラスがより具体的なすべてのメソッドを保持する継承でこれを実装できるかどうか疑問に思っています。

4

4 に答える 4

6

evt が動的に渡されたとしても、ProcessEvent は仮想として宣言されないため、うまくいきません。これは、ProcessEvent への呼び出しがコンパイルされると、基本クラスで見つかったメソッドの唯一の実装にリンクされ、派生クラスの実装は実行されないことを意味します。さらに、派生クラスでは署名が異なるため、単純に ProcessEvent を virtual として宣言することはできません。

コードが期待どおりに機能するためには、派生クラスで ReceiveEvent をオーバーライドして、まったく同じにすることができます。

  public override void ReceiveEvent(Event evt)
    {
        ProcessEvent(evt as dynamic);
    }

未処理のイベントを基本クラスで管理する場合は、基本クラスの Process イベントの修飾子を protected に変更するだけです (そうしないと、オーバーライドされたバージョンの ReceiveEvents によって呼び出されたときに実行できません)。

于 2012-05-21T10:35:42.483 に答える
2

メソッドが基本クラスにvirtual/ではなく、メソッドが派生クラスのようにabstractマークされていない場合、そのメソッドは機能しません。override

また、ここの使い方がわかりませんdynamic

于 2012-05-21T10:11:57.503 に答える
0

ProcessEvent にヒットしたときの「evt」のタイプは何ですか?

Using Type dynamic をご覧ください 。

型は静的型ですが、動的型のオブジェクトは静的型チェックをバイパスします。ほとんどの場合、オブジェクト型を持つように機能します。

したがって、evt は ではありませんSpecificEvent

于 2012-05-21T10:11:32.590 に答える
0

期待される動作を得るには、仮想メソッドをオーバーライドする必要があります。

public DerivedClass: BaseClass
{
  private override void ReceiveEvent(Event evt)
  { 
      // Process your event here.
  }
}

このコードでReceiveEventは、基本クラスでは呼び出されないため、フォールバックProcessEventは呼び出されません。

使用する理由はありませんdynamic

于 2012-05-21T10:18:24.510 に答える