Dynamic dispatch to derived class in C#

风格不统一 提交于 2021-02-07 12:33:17

问题


I'm trying to do the following:

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 hit the fallback method instead of the one in the derived class. I use dynamic dispatch within the same class all the time and find it really useful/clean. Will it not work with derived classes as illustrated in the example above?

EDIT: There seems to be some confusion in the answers. Basically i use the following design all the time:

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
    { 

    }
}

Works great for when you don't know the exact type beforehand and you don't want to use a big switch statement. Just wondering if this can be implemented with inheritance where the base class holds the fallback method and the derived class holds all the more specific methods.


回答1:


It's not working for you because even if evt is passed dynamic, ProcessEvent is not declared as virtual. This means that when the call to ProcessEvent is compiled, it is linked to the only implementation of the method that is found in the base class, and the ones in the derived classes will never be executed. Furthermore, you can't simply declare your ProcessEvent as virtual, since the signature will be different in the derived classes.

In order for your code to work as expected you could just override ReceiveEvent in the derived classes leaving it exactly the same:

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

If you want to manage the unhandled events in the base class, just change the modifier of Process event in the base class to protected (otherwise it can't be executed when called by the overridden version of ReceiveEvents).




回答2:


If the method is not virtual/abstract in the base class, and the method is not marked as override in the derived class, it will never work.

Also, I dont understand the usage of dynamic here.




回答3:


What is the type of your "evt" when it hit ProcessEvent ?

You may take a look to Using Type dynamic :

The type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object.

So, evt is not a SpecificEvent.




回答4:


To get the expected behaviour you should override the virtual method:

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

With this code, ReceiveEvent in the base class won't be called, thus the fallback ProcessEvent won't be called.

There is no reason to use dynamic.



来源:https://stackoverflow.com/questions/10683210/dynamic-dispatch-to-derived-class-in-c-sharp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!