2012-05-21 14 views
6

sto cercando di fare quanto segue:dinamica spedizione verso classe derivata in C#

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 colpito il metodo di ripiego al posto di quello della classe derivata. Uso la spedizione dinamica all'interno della stessa classe per tutto il tempo e la trovo davvero utile/pulita. Non funzionerà con le classi derivate come illustrato nell'esempio sopra?

MODIFICA: Sembra esserci un po 'di confusione nelle risposte. Fondamentalmente io uso il seguente disegno per tutto il tempo:

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 
    { 

    } 
} 

funziona alla grande per quando non si conosce il tipo esatto in anticipo e non si desidera utilizzare una grande dichiarazione interruttore. Mi chiedo solo se questo può essere implementato con ereditarietà in cui la classe base detiene il metodo di fallback e la classe derivata contiene tutti i metodi più specifici.

+0

La mia ipotesi è che ReceiveEvent venga chiamato sulla BaseClass anziché su DerivedClass. Hai provato a sovrascrivere ReceiveEvent su DerivedClass? È virtuale, quindi puoi fare 'public override void ReceiveEvent (Event evt)' Ecco alcune ulteriori informazioni sui metodi Virtual: http://msdn.microsoft.com/en-us/library/aa645767%28v=vs.71%29. aspx – Davio

risposta

4

Non funziona per voi perché anche se evt è passato dinamico, ProcessEvent non è dichiarato come virtuale. Ciò significa che quando la chiamata a ProcessEvent viene compilata, è collegata all'unica implementazione del metodo che si trova nella classe base e quelli nelle classi derivate non verranno mai eseguiti. Inoltre, non puoi semplicemente dichiarare ProcessEvent come virtuale, poiché la firma sarà diversa nelle classi derivate.

Affinché il codice a funzionare come previsto si può solo ignorare ReceiveEvent nelle classi derivate lasciandola esattamente la stessa cosa:

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

Se si desidera gestire gli eventi non gestite nella classe base, basta cambiare il modificatore dell'evento Process nella classe base su protected (altrimenti non può essere eseguito se chiamato dalla versione sovrascritta di ReceiveEvents).

+0

Sì, è così che ho scritto ora. Indovina è la soluzione più vicina. Speravo di poter spostare il fallback sulla classe base, ma sembra che non sia possibile in base al modo in cui descrivi il processo di compilazione. Saluti. –

+0

Oh, ho appena notato l'ultimo paragrafo. Lo proverò! –

1

Qual è il tipo di "evt" quando si verifica ProcessEvent?

Si può dare un'occhiata a Using Type dynamic:

Il tipo è un tipo statico, ma un oggetto di tipo dinamico bypassa controllo di tipo statico. Nella maggior parte dei casi, funziona come se fosse di tipo oggetto.

Quindi, evt non è un SpecificEvent.

+0

Sto usando dinamico. –

+0

Prima, la dinamica sarà considerata come oggetto. Quindi, l'ereditarietà sembra essere errata, senza "virtuale"/"astratto"/"sovrascrittura" o anche "nuovo" sui metodi. Si può provare a mettere virtual sui metodi ProcessEvent nella BaseClass e sovrascrivere su DerivedClass. – kerrubin

3

Se il metodo non è virtual/abstract nella classe base e il metodo non è contrassegnato come override nella classe derivata, non funzionerà mai.

Inoltre, non capisco l'utilizzo di dynamic qui.

+0

dinamico qui è usato come un buon modo per instradare tipi di oggetti sconosciuti ai loro gestori appropriati, senza usare un'istruzione switch –

1

per ottenere il comportamento previsto è necessario eseguire l'override del metodo virtuale:

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

Con questo codice, ReceiveEvent nella classe di base non sarà chiamato, così il fallback non sarà chiamato ProcessEvent.

Non vi è alcun motivo per utilizzare dynamic.

Problemi correlati