动态调度到 C# 中的派生类
本文关键字:派生 动态调度 | 更新日期: 2023-09-27 18:34:43
我正在尝试执行以下操作:
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");
}
}
特定事件命中回退方法,而不是派生类中的回退方法。我一直在同一类中使用动态调度,并发现它非常有用/干净。它不适用于上面示例中所示的派生类吗?
编辑:答案似乎有些混乱。基本上我一直使用以下设计:
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 语句时,它非常有用。只是想知道这是否可以通过继承来实现,其中基类保存回退方法,派生类保存所有更具体的方法。
它不适合您,因为即使 evt 是动态传递的,ProcessEvent 也不会声明为虚拟的。这意味着,当编译对 ProcessEvent 的调用时,它将链接到在基类中找到的方法的唯一实现,并且永远不会执行派生类中的方法。此外,您不能简单地将 ProcessEvent 声明为虚拟,因为派生类中的签名会有所不同。
为了使您的代码按预期工作,您只需在派生类中重写 ReceiveEvent,使其完全相同:
public override void ReceiveEvent(Event evt)
{
ProcessEvent(evt as dynamic);
}
如果要管理基类中未处理的事件,只需将基类中的 Process 事件的修饰符更改为受保护(否则在被重写的 ReceiveEvents 版本调用时无法执行(。
如果该方法在基类中未virtual
/abstract
,并且该方法未在派生类中标记为override
,则它将永远不起作用。
另外,我不明白这里dynamic
的用法。
你的"evt"在点击ProcessEvent时是什么类型?
你可以看看 使用类型 动态 :
类型是静态类型,但动态类型的对象会绕过 静态类型检查。在大多数情况下,它的功能就像它有类型 对象。
所以,evt 不是SpecificEvent
.
要获得预期的行为,您应该覆盖虚拟方法:
public DerivedClass: BaseClass
{
private override void ReceiveEvent(Event evt)
{
// Process your event here.
}
}
使用此代码,不会调用基类中的ReceiveEvent
,因此不会调用回退ProcessEvent
。
没有理由使用dynamic
.