我正在用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)
的例外是由于运行时仅检查Method
及其基类的DynamicBase
重载。如果我想让它在Method
中调用DynamicSub
,则需要使用与基类中完全相同的代码覆盖Run
。
因此,如何在没有覆盖的情况下实现此行为?
[如果不是,如何通过编程复制虚拟方法(我的意思是IL代码)来为子类动态发出对Run
的覆盖?这样,(我的lib的)用户就不必自己将Run
方法复制到子类中。
Console.WriteLine(Method((dynamic)aha));
[在编译时解析Method
,实际上只是DynamicBase.Method
。
您想要的是动态解析Method
,这意味着您在其上调用该方法的引用必须为dynamic
:
Console.WriteLine(((dynamic)this).Method((dynamic)aha));
请注意,对于您想要实现的目标,很可能有更多的类型安全的解决方案。如果您正在努力规避C#的所有类型安全性,则可能需要研究更多动态语言-带有NodeJS的JavaScript是一个不错的选择。