2011-05-25 47 views
2

说我有下面的代码:在编译时未知类型时如何选择方法重载?

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的我的希望是能够处理特定事件类型的我期待的方法,并具有将抛出一个包罗万象的方法如果出于某种原因提供了意外的事件类型。

什么我发现,虽然是通用的方法被调用,即使T是类型ThingyCreatedEvent的,除非我明确地投它:

Handle(evt.Payload as ThingyCreatedEvent); 

我得到,如果同样的结果,而不是通用Handle方法,我用一个Object类型参数定义一个Handle方法。

任何人都可以解释这一点吗?我想更好地了解这里发生的事情。我希望它能根据运行时提供的实际类型进行调度。

+1

.NET泛型不是C++模板。 C++模板不是.NET泛型。没有人提供运行时分派。 – 2011-05-25 19:22:06

回答

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); 
} 
+0

感谢Jon - 我使用.Net 4,所以它是动态的! – 2011-05-25 19:10:04

+0

而且,Jon和Maciek都不相干 - 那真的。真。快。哇。 – 2011-05-25 19:13:17

+4

@Remi:不是。花了3分钟。我对延迟表示歉意,并会在下次尝试帮助更快;) – 2011-05-25 19:16:03

4

泛型在编译时被解析 - 编译器需要知道T的类型是什么。如果你想使用一个将在运行时被解析的类型,你应该查找关键字“dynamic ”。

+0

Nitpick:'动态'只是*上下文*关键字:) – 2011-05-25 19:10:27

+0

heh cheers Jon :) – Maciek 2011-05-25 19:27:45

相关问题