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

时间:2012-03-27 13:36:01

标签: c# .net 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!");
        }
    }
}

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

修改 更改main以使c.M具有true或null参数仍会选择不正确的方法。

3 个答案:

答案 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参数,优先