为什么不调用重载方法?

Tom*_*son 13 .net c#

我认为被调用的方法是运行时决定的,还是我错过了什么?示例代码:

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{}
Run Code Online (Sandbox Code Playgroud)

我以为我会得到:

ImplA
ImplB
Run Code Online (Sandbox Code Playgroud)

作为输出,但它打印Base impl.有什么我可以做的,以获得重载方法而不输入输入?

Ste*_*ger 18

编译器选择过载.对于这里的电话:

internal void DoStuff<T>(T input) where T : SomeBase
{
    HiThere(input);
}
Run Code Online (Sandbox Code Playgroud)

它选择了一个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);
}
Run Code Online (Sandbox Code Playgroud)

  • 或者使用`dynamic`:`HiThere((动态)输入);`这会将重载决议移动到运行时,其中确切的`input`类型是已知的. (6认同)
  • 另一种可能性是他想做[`double dispatch`](http://en.wikipedia.org/wiki/Double_dispatch)或使用[`visitor pattern`](http://en.wikipedia.org/wiki/Visitor_pattern). (2认同)