C#函数重载规则

时间:2010-08-16 14:13:24

标签: c# clr overloading

有关函数重载的规则是什么?

我有以下代码:

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在运行时选择了最佳匹配!

2 个答案:

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