Подтвердить что ты не робот

Почему вызов не перегружается?

Я думал, что метод, который вызывается, называется временем выполнения, или я что-то пропустил? Пример кода:

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{}

Я думал, что получу:

ImplA
ImplB

но он печатает Base impl. Есть ли что-нибудь, что я могу сделать, чтобы получить перегруженный метод без ввода ввода?

4b9b3361

Ответ 1

Перегрузки выбираются компилятором. Для вызова здесь:

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

он выбирает один с SomeBase, потому что все, что у него есть во время компиляции.

То, что вы, скорее всего, хотите, - это переопределения. Это означает, что в наследники 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);
}

Ответ 2

Во время компиляции выбираются перегрузки.
Переопределения выбираются во время выполнения.

Здесь компиляторы знают только, что T можно назначить SomeBase, но ничего больше. Фактически, если бы он работал так, как вы ожидали, вы могли бы полностью пропустить часть where T : SomeBase. Причина, в которой вы нуждаетесь, заключается в том, что компилятор должен знать эту информацию, чтобы проверить, что можно вызвать на предоставленный объект.