为什么不调用重载方法?

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

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 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 。 有什么我可以做的,以获得重载方法而不输入输入?

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

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

它选择了SomeBase ,因为这就是编译时的全部内容。

你最想要的是覆盖。 这意味着必须将不同的逻辑放入SomeBase的inheritance者中:

 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); } 

在编译期间选择过载。
在运行时选择覆盖。

在这里,编译器只知道T可以分配给SomeBase ,但没有别的。 实际上,如果它按预期工作,你将能够完全跳过where T : SomeBase部分。 您需要它的原因是编译器需要知道该信息,以便检查在提供的对象上可以调用的内容。