方法重载

当我使用TemplateA类型的参数调用EntryPoint时,我总是收到exception,因为总是调用第一个重载。
我期望发生的是由于动态绑定将调用最具体的方法(第二次重载)。
有什么想法吗?

private object _obj; public void EntryPoint(object p) { myFunc(p); } //first overload private void myFunc(object container) { throw new NotImplementedException(); } //second overload private void myFunc(TemplateA template) { _obj = new ObjTypeA(template); } //third overload private void myFunc(TemplateB template) { _obj = new ObjTypeB(template); } 

如果使用dynamic而不是object则可以在C#4.0中执行此操作。 如果您想尝试一下,请下载Visual Studio 2010 Beta。 在此之前,编译器会根据参数的编译时类型选择要调用的方法。

从您的问题中不清楚您是否了解普通的单调度多态,因为它可以解决您的示例问题。

 class TemplateBase { public virtual object MyFunc() { throw new NotImplementedException(); } } class TemplateA : TemplateBase { public override object MyFunc() { return new ObjTypeA(this); } } class TemplateB : TemplateBase { public override object MyFunc() { return new ObjTypeB(this); } } 

其他地方:

 private object _obj; public void EntryPoint(TemplateBase p) { _obj = p.MyFunc(); } 

当您无法修改TemplateN类时,还有其他选择。 最简单的方法是让EntryPoint方法可以访问从Type到某个委托的Dictionary映射。

 Dictionary> _myFuncs; _myFuncs.Add(typeof(TemplateA), o => new ObjTypeA((TemplateA)o)); _myFuncs.Add(typeof(TemplateB), o => new ObjTypeB((TemplateA)o)); 

然后,它可以查找委托以执行传递给它的对象类型。

 Func f = _myFuncs[p.GetType()]; _obj = f(p); 

但是,如果要模拟虚函数的确切工作方式,则需要注意inheritance层次结构。

我期望发生的是由于动态绑定将调用最具体的方法(第二次重载)。

你在哪里看到动态绑定? 变量的静态类型是object 。 除非您直接在其上调用虚方法,否则不会发生动态调度。 在编译时完全静态地解决了重载。

Eric Lippert有一篇相关的博客文章: Double Your Dispatch,Double Your Fun 。

当您使用类型为TemplateA的参数调用EntryPoint()时,它将强制转换为object 。 因此,对myFunc(p)的后续静态绑定调用将使用myFunc(p)类型的参数进行。

我认为在EntryPoint上下文中,编译器知道应该调用第一个重载,因为它是静态绑定而不是动态