views:

221

answers:

2

What are the rules regarding function Overloading?

I have the following code:

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

when I call the above code with:

genericFunc<DerivedFromComponent>();

I expect the more specific overloadedFunction to be called, however the catch all function is called instead, why is this?. When stepping through the above code the type T is indeed DerivedFromComponent, I thought that the CLR picked the best possible match at runtime!

+14  A: 

The compiler performs overload resolution within genericFunc when that method is compiled. At that point it doesn't know what type argument you're going to provide, so it only knows that it can call the first of your overloads.

Your example using generics makes life more complicated, but overloads are always resolved at compile-time (assuming you're not using dynamic).

A simple example not using generics:

void Foo(string text) { }
void Foo(object o) {}
...
object x = "this is a string";
Foo(x);

would call the second overload, because the compile-time type of x is just object.

For more on this, read my recent article on overloading.

Jon Skeet
+2  A: 

Jon Skeet is right on with regard to the fact that overload resolution is determined at compile time. I thought I'd add another answer that was not the point of your question but interesting to note nonetheless.

In C# 4, the dynamic keyword can be used to defer the overload resolution until runtime. Consider the following snippet which prints:

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>();
}
Josh Einstein
Doh, and in the time it took me to write this Jon Skeet has also noted dynamic.
Josh Einstein
If only I could get management to spring for a shiny new copy of VS2010 all my troubles would evaporate ... but alas I am stuck with .NET 3.5 and VS2008!
TK
To be honest, I wouldn't recommend using the above code to solve the problem. It's not a very good example of a justified use for dynamic resolution.
Josh Einstein