当编译时类型未知时,如何选择方法重载
本文关键字:选择 方法 重载 类型 编译 未知 何选择 | 更新日期: 2023-09-27 17:57:51
假设我有以下代码:
public class SomeClass
{
// Other stuff...
public void ApplyEvent<T>(IPublishedEvent<T> evt)
{
Handle(evt.Payload);
}
protected virtual void Handle(ThingyCreatedEvent evt)
{
Code = evt.Code;
Label = evt.Label;
}
protected virtual void Handle<T>(T evt)
{
throw new NotImplementedException(
String.Format("Not set to handle {0}", evt.GetType().FullName));
}
}
evt。Payload的类型是T。我希望能够处理我期望的特定事件类型的方法,并有一个catch-all方法,如果出于某种原因提供了意外的事件类型,该方法将抛出。
不过,我发现,即使T是ThingyCreatedEvent类型,也会调用泛型方法,除非我显式强制转换它:
Handle(evt.Payload as ThingyCreatedEvent);
如果我定义了一个带有Object类型参数的Handle方法,而不是通用的Handle法,我会得到同样的结果。
有人能解释一下吗?我想更好地了解这里发生了什么。我本以为它会根据运行时提供的实际类型进行调度。
泛型在编译时解析-编译器需要知道T的类型是什么。如果你想使用将在运行时解析的类型,你应该查找关键字"dynamic"。
所有代码(包括重载解析)在正常编译时都会编译一次,除非有约束,否则必须在不知道T
是什么的情况下做出重载决策。调用Handle(evt.Payload);
的方法只在知道evt.Payload
的类型是T
的情况下解析一次,因此它必须解析为Handle<T>(T evt)
。
如果你真的想在执行时解决过载问题,如果你使用的是C#4,你可以使用动态键入:
public void ApplyEvent<T>(IPublishedEvent<T> evt)
{
dynamic payload = evt.Payload;
Handle(payload);
}