C#选择与可选参数和多级inheritance所期望的方法不同的方法

在给定的示例中(对于代码样式很抱歉,它是为了一个紧凑的自包含repro),被调用的方法总是B中的虚方法,它有附加的整数参数,而我希望这个方法在C将是一个叫做的人。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MethodChoosing { class Program { static void Main(string[] args) { C c = new C(); cM(); Console.ReadKey(); } } public class A { public virtual void M(bool? a = null) { Console.WriteLine("base base"); } } public class B : A { public override void M(bool? a = null) { Console.WriteLine("base override"); } public virtual void M(bool? a = null, int? b = null) { Console.Write("base new"); } } public class C : B { public override void M(bool? a = null) { Console.WriteLine("pick me!"); } } } 

哪个输出“基础新”。 这显然不是我预期的行为,是否有人能够解释推理?

编辑:更改main以使cM具有true或null参数仍然选择不正确的方法。

规范的第7.4节规定,覆盖方法将从成员查找期间考虑的可访问方法集中排除。 考虑到原始问题中的方法,类A有一个非重写方法,类B有一个非重写方法,类C没有任何方法。 从集合中的两个方法,编译器选择最派生类中的匹配方法(在本例中为类B,“基本新”函数)。

如果B类中的匹配函数不存在,则最佳函数匹配将是A类中的虚函数。在这种情况下,作为虚拟对象的运行时类型将用于选择哪个被覆盖的函数将选择A,B或C类。 当问题被陈述时,因为该方法被称为C类对象,将是“接我!” function。

那是什么叫做模糊调用。 由于您有两个方法仅由一个可选参数分隔,因此应用程序似乎选择了可以满足最多参数的方法。

编辑:正如@lazyberezovsky所说,我在那里并不完全正确。 如果你有一个方法,它可以满足NO参数,这是优先的

使用cM() ,假设调用M(null, null) 。 这就是可选参数的工作方式。 如果要调用CM(null) ,请在CM(null)调用CM(null)或覆盖M(bool? a = null, int? b = null)