说我有以下代码:
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方法,我会得到相同的结果。
任何人都能解释一下吗?我想更好地了解这里发生了什么。我原以为它会根据运行时提供的实际类型进行调度。
答案 0 :(得分:4)
泛型在编译时被解析 - 编译器需要知道什么是T的类型。如果你想使用一个将在运行时解析的类型,你应该查找关键字“dynamic”
答案 1 :(得分:2)
所有代码 - 包括重载解析 - 在正常编译时编译一次,并且必须在不知道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);
}