有关函数重载的规则是什么?
我有以下代码:
public T genericFunc<T>() where T : Component, new()
{
T result = new T();
overloadedFunction( result );
}
private overloadedFunction ( Component c ) // catch all function
private overloadedFunction ( DerivedFromComponent dfc) // specific function
当我用以下代码调用上述代码时:
genericFunc<DerivedFromComponent>();
我希望调用更具体的overloadedFunction,但是调用catch all函数,为什么会这样?单步执行上面的代码时,类型T确实是DerivedFromComponent,我认为CLR在运行时选择了最佳匹配!
答案 0 :(得分:15)
编译该方法时,编译器在genericFunc
内执行重载解析。那时它不知道你要提供什么类型的参数,所以它只知道它可以调用你的第一个重载。
使用泛型的示例会使生活变得更复杂,但是在编译时总是解决重载(假设您没有使用dynamic
)。
不使用泛型的简单示例:
void Foo(string text) { }
void Foo(object o) {}
...
object x = "this is a string";
Foo(x);
会调用第二个重载,因为x
的编译时类型只是对象。
有关详情,请阅读我最近的article on overloading。
答案 1 :(得分:3)
Jon Skeet对于在编译时确定重载决策这一事实是正确的。我想我会添加另一个不是你的问题的答案,但有趣的是要注意。
在C#4中,dynamic关键字可用于将重载决策推迟到运行时。请考虑以下代码段打印:
Base!
Derived!
class Base {
}
class Derived : Base {
}
void DoSomething(Base x) {
Console.WriteLine("Base!");
}
void DoSomething(Derived x) {
Console.WriteLine("Derived!");
}
void DoSomething<T>() where T: Base, new() {
dynamic x = new T();
DoSomething(x);
}
void Main()
{
DoSomething<Base>();
DoSomething<Derived>();
}