简体   繁体   English

为什么不调用重载方法?

[英]Why isn't the overloaded method getting called?

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 . 作为输出但它打印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. 它选择SomeBase ,因为这就是编译时的全部内容。

What you most probably want is overrides. 你最想要的是覆盖。 This means that the different logic has to be put into the inheritors of 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);
}

Overloads are selected during compilation. 在编译期间选择过载。
Overrides are selected during runtime. 在运行时期间选择覆盖。

Here, compilers only knows that T can be assigned to SomeBase , but nothing else. 在这里,编译器只知道T可以分配给SomeBase ,但没有别的。 Actually, if it worked as you expected, you would be able to completely skip the where T : SomeBase part. 实际上,如果它按预期工作,你将能够完全跳过where T : SomeBase部分。 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. 您需要它的原因是编译器需要知道该信息,以便检查可以在提供的对象上调用的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM