在C#中动态调度派生类

时间:2012-05-21 10:04:44

标签: c# c#-4.0 dispatch

我正在尝试执行以下操作:

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 个答案:

答案 0 :(得分:6)

它不适合您,因为即使evt是动态传递的,ProcessEvent也不会声明为虚拟。这意味着当编译对ProcessEvent的调用时,它将链接到基类中找到的方法的唯一实现,并且永远不会执行派生类中的实现。此外,您不能简单地将ProcessEvent声明为虚拟,因为签名在派生类中会有所不同。

为了使您的代码按预期工作,您可以在派生类中重写ReceiveEvent,使其完全相同:

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

如果要管理基类中未处理的事件,只需将基类中的Process事件的修饰符更改为protected(否则在被重写的ReceiveEvents版本调用时不能执行)。

答案 1 :(得分:2)

如果该方法在基类中不是virtual / abstract,并且该方法在派生类中未标记为override,则它将永远不会起作用。

另外,我在这里不了解dynamic的用法。

答案 2 :(得分:0)

点击ProcessEvent时“evt”的类型是什么?

您可以查看Using Type dynamic

  

类型是静态类型,但是动态绕过类型的对象   静态类型检查。在大多数情况下,它的功能类似于它的类型   对象

所以,evt不是SpecificEvent

答案 3 :(得分:0)

要获得预期的行为,您应该覆盖虚拟方法:

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

使用此代码,将不会调用基类中的ReceiveEvent,因此不会调用回退ProcessEvent

没有理由使用dynamic