Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# rules of function overloading

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!

like image 326
TK. Avatar asked Aug 16 '10 14:08

TK.


2 Answers

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.

like image 88
Jon Skeet Avatar answered Sep 24 '22 00:09

Jon Skeet


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>();
}
like image 34
Josh Avatar answered Sep 23 '22 00:09

Josh