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

one*_*e-t 2 .net c# inheritance optional-parameters

在给定的示例中(对于代码样式而言,它是为了一个紧凑的自包含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!");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Tar*_*gon 5

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

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