【发布时间】:2020-09-25 02:41:17
【问题描述】:
我正在用 C# 编写一个游戏服务器,现在我遇到了一个问题,即调用适当的方法按其类型正确处理每条消息。这个简单的代码说明了我当前的解决方案:
public class DynamicBase
{
public int Method(Abc abc) => 2;
public virtual void Run()
{
IAbc abc = new Abc();
Console.WriteLine(Method((dynamic)abc)); // print 2
IAbc aha = new Aha();
// expecting print 3
Console.WriteLine(Method((dynamic)aha)); //Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
}
}
public class DynamicSub : DynamicBase
{
public int Method(Aha a) => 3;
}
public class Abc : IAbc { }
public class Aha : IAbc { }
public interface IAbc { }
//In Main(): new DynamicSub().Run();
Method((dynamic)aha) 的异常是由于运行时仅检查 DynamicBase 及其基类的 Method 重载。如果我希望它在DynamicSub 中调用Method,那么我需要在基类中使用完全相同的代码覆盖Run。
那么,如何在没有覆盖的情况下实现这种行为?
如果不是,我如何通过以编程方式复制虚拟方法(我的意思是 IL 代码)为子类动态发出 Run 的覆盖?这样我的用户(我的库)就不必自己将Run 方法复制到子类。
【问题讨论】:
-
如果某些继承者
DynamicSub2没有Method(Aha a),应该为Console.WriteLine(Method((dynamic)aha));调用什么? -
您正试图实现非常奇怪的行为。您永远不应该尝试在基类中调用派生类方法。你想解决什么问题?
-
@GuruStron 抛出 RuntimeBinderException。如果我想使异常保持沉默,那么我将拥有
Method(object o) -
@VladaxLe 说我有一个
PeerBase类来处理来自客户端的请求。它反序列化对 POCO 的传入请求。每个 POCO 将由一个适当的Method以不同方式处理,它充当子类的接口 -
C# 和其他 OOP 语言在编译时或运行时解析方法。虚拟方法在运行时解析,重载方法在编译时解析。我的情况是我试图调用重载方法,它们在编译时解决,所以我通过强制
this为dynamic在运行时解决它。