在给定的例子中(对于代码样式而言,它是为了一个紧凑的自包含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();
c.M();
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以使c.M
具有true或null参数仍会选择不正确的方法。
答案 0 :(得分:5)
规范的第7.4节规定,覆盖方法将从成员查找期间考虑的可访问方法集中排除。考虑到原始问题中的方法,类A有一个非重写方法,类B有一个非重写方法,类C没有任何方法。从集合中的两个方法,编译器选择最派生类中的匹配方法(在本例中为类B,“基本新”函数)。
如果B类中的匹配函数不存在,则最佳函数匹配将是A类中的虚函数。在这种情况下,作为虚拟,对象的运行时类型将用于选择被覆盖的内容将选择A,B或C类中的函数。当问题被陈述时,因为该方法被称为C类对象,将是“接我!”功能
答案 1 :(得分:1)
假设c.M()
被调用M(null, null)
。
这就是可选参数的工作方式。
如果您希望调用C.M
,请使用C.M(null)
进行调用,或覆盖M(bool? a = null, int? b = null)
课程中的C
。
答案 2 :(得分:1)
那是什么叫做模糊调用。由于您有两个方法仅由一个可选参数分隔,因此应用程序似乎选择了可以满足最多参数的方法。
编辑:正如@lazyberezovsky所说,我在那里并不完全正确。如果你有一个方法,它可以满足NO参数,优先