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 声明为虚拟,因为派生类中的签名会有所不同。

为了让您的代码按预期工作,您可以在派生类中覆盖 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 回答