c# with Why isn't the overloaded method getting called?




why we use method overloading in c# (2)

I thought the method that is getting called is decided runtime, or have I missed something? Sample code:

class Program
{
    static void Main(string[] args)
    {
        var magic = new MagicClass();
        magic.DoStuff(new ImplA());
        magic.DoStuff(new ImplB());
        Console.ReadLine();
    }
}
class MagicClass
{
    internal void DoStuff<T>(T input) where T : SomeBase
    {
        HiThere(input);
    }

    void HiThere(SomeBase input)
    {
        Console.WriteLine("Base impl");
    }

    void HiThere(ImplA input)
    {
        Console.WriteLine("ImplA");
    }

    void HiThere(ImplB input)
    {
        Console.WriteLine("ImplB");
    }
}

abstract class SomeBase
{

}
class ImplA : SomeBase{}
class ImplB : SomeBase{}

I thought I would get:

ImplA
ImplB

as output but it prints Base impl. Is there anything I can do to get the overloaded method without casting the input?


Overloads are chosen by the compiler. For the call here:

internal void DoStuff<T>(T input) where T : SomeBase
{
    HiThere(input);
}

it chooses the one with SomeBase, because that's all it has at compile time.

What you most probably want is overrides. This means that the different logic has to be put into the inheritors of SomeBase:

abstract class SomeBase
{
  abstract string Name { get; }
}
class ImplA : SomeBase{ override string Name { get { return "ImplA"; } } }
class ImplB : SomeBase{ override string Name { get { return "ImplB"; } } }

void HiThere(SomeBase input)
{
    Console.WriteLine(input.Name);
}

Overloads are selected during compilation.
Overrides are selected during runtime.

Here, compilers only knows that T can be assigned to SomeBase, but nothing else. Actually, if it worked as you expected, you would be able to completely skip the where T : SomeBase part. The reason you need it is that compiler needs to know that information in order to check what can be called on the provided object.





.net