在编译时不知道类型时如何选择方法重载?

时间:2011-05-25 19:05:12

标签: c# .net generics

说我有以下代码:

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方法,我会得到相同的结果。

任何人都能解释一下吗?我想更好地了解这里发生了什么。我原以为它会根据运行时提供的实际类型进行调度。

2 个答案:

答案 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);
}