2012-05-21 8 views
6

私は、次の操作を実行しようとしている:動的ディスパッチング

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は、フォールバック方式の代わりに、派生クラスで1を押してください。私はいつも同じクラス内の動的ディスパッチを使用して、それが本当に有用であるか/きれいであることを見いだします。上記の例に示すように派生クラスではうまくいかないでしょうか?

編集: 回答には多少の混乱があるようです。

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文を使用しないとき のための素晴らしい作品

:基本的に私は次のデザインのすべての時間を使用します。基本クラスがフォールバックメソッドを保持し、派生クラスがすべてのより具体的なメソッドを保持する継承でこれを実装できるかどうかは不思議です。

+0

私の推測では、ReceiveEventがDerivedClassではなくBaseClassで呼び出されていると思います。 DerivedClassでReceiveEventをオーバーライドしようとしましたか?これは仮想的なので、 'public override void ReceiveEvent(Event evt)'を実行することができます。バーチャルメソッドの詳細は、次のとおりです。http://msdn.microsoft.com/en-us/library/aa645767%28v=vs.71%29 aspx – Davio

答えて

4

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

あなただけのまったく同じことを残して派生クラスでたreceiveEventをオーバーライドする可能性が期待どおりに動作するようにコードためには:

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

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

+0

これはどうやって書いたのですか。それが最も近い解決策だと思います。フォールバックをベースクラスに移すことができると期待していましたが、コンパイルプロセスを記述する方法に基づいて可能ではないようです。乾杯。 –

+0

私はちょうど最後の段落に気づいた。私はそれを試してみましょう! –

1

「evt」のタイプはProcessEventに当たったときのタイプは何ですか?

あなたはUsing Type dynamicに見てみることがあります。

型は静的な型ですが、型ダイナミックのオブジェクトが 静的型チェックをバイパスします。ほとんどの場合、それはタイプ オブジェクトのように機能します。

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

+0

私は動的を使用しています。 –

+0

まず、ダイナミックはオブジェクトとして考えられます。 次に、メソッド上で "仮想"/"抽象"/"オーバーライド"または "新規"さえなく、継承が正しくないように見えます。 BaseClassのProcessEventメソッドに仮想を置き、DerivedClassを上書きすることができます。 – kerrubin

3

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

また、私はここでdynamicの使用法を理解していません。

+0

dynamicここでは、switchステートメントを使用せずに、未知のオブジェクト型を適切なハンドラにルーティングするための素晴らしい方法として使用されています。 –

1

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

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

を、基底クラスでReceiveEventは、フォールバックProcessEventが呼び出されることはありませんので、呼び出されません。

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

関連する問題