Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用错误方法的派生类_C#_Inheritance_Overloading - Fatal编程技术网

C# 使用错误方法的派生类

C# 使用错误方法的派生类,c#,inheritance,overloading,C#,Inheritance,Overloading,我已经将我的代码简化为 internal class Program { private static void Main(string[] args) { Child d = new Child(); int i = 100; d.AddToTotal(i); Console.ReadKey(); } private class Parent { public virt

我已经将我的代码简化为

 internal class Program
{
    private static void Main(string[] args)
    {
        Child d = new Child();
        int i = 100;
        d.AddToTotal(i);

        Console.ReadKey();
    }

    private class Parent
    {
        public virtual void AddToTotal(int x)
        {
            Console.WriteLine("Parent.AddToTotal(int)");
        }
    }

    private class Child : Parent
    {
        public override void AddToTotal(int number)
        {
            Console.WriteLine("Child.AddToTotal(int)");
        }

        public void AddToTotal(double currency)
        {
            Console.WriteLine("Child.AddToTotal(double)");
        }
    }
}
问题是这需要

public void AddToTotal(double currency)
虽然我用int调用它,它应该使用

public override void AddToTotal(int number)
使用父级返回预期结果

 Parent d = new Child();
 int i = 100;
 d.AddToTotal(i);
更新:

感谢@Jan和@azyberezovsky为我指明了方向。我已经在基类中添加了一个虚拟空方法来解决这个问题。

T类型中名称N的a处理如下:

首先,构造在T中声明的名为N的所有可访问成员集和T的基类型。包含覆盖修饰符的声明将从集合中排除。如果不存在名为N的成员且这些成员是可访问的,则查找不会产生匹配项,并且不会计算以下步骤

因此,当您使用子类型的变量时

Child d = new Child();
int i = 100;
d.AddToTotal(i);
方法
public override void AddToTotal(int number)
被排除在集合之外,我们只有一个名为N的方法。Int隐式转换为double,因此没有发生错误。

to解释了发生这种情况的技术原因。为了方便起见,我把答案写在这里,但所有的积分都是由于

请参阅C#语言规范中关于 和。派生类的重写方法 由于有关成员查找和基的规则,不是候选项 基于重载解析,类方法不是最佳匹配 规则

第7.3节

首先,名为N的所有可访问(第3.5节)成员的集合 在T中声明,并构造T的基本类型(第7.3.1节)。 包含重写修饰符的声明将从 设置如果名为N的成员不存在且不可访问,则查找 不生成匹配项,并且不计算以下步骤

第7.4.2节:

这些上下文中的每一个都定义了候选函数成员集 以及参数列表,如中所述 详情请参见上述章节。例如 方法调用的候选对象不包括标记为 重写(第7.3节),基类中的方法不是候选方法 如果派生类中的任何方法适用(第7.5.5.1节)。 (强调矿山)


好的,我能够复制结果,并确保这不仅仅是一个输入错误,其中int重载的方法名称不同。
d.AddToTotal(number:I)
调用int重载,正如预期的那样,但您不必这样做……请参阅此答案以获得解释:此方法是否隐藏?如果签名不一样,你能隐藏一个基本方法吗?我觉得很奇怪,重载解析会给新方法比重写方法更高的优先级,但显然它确实…奇怪。有人知道这背后的原因吗?@Servy请看埃里克·利珀特的回答:@Servy:很多人觉得这个选择很奇怪,但有两个很好的理由。第一个原因是编写派生类方法的开发人员比编写基类方法的开发人员拥有更多的信息。具体来说,派生类开发人员知道派生类的实现细节,但基类开发人员不知道。重载解析应该选择由最了解用户实际使用的对象的人编写的方法。@Servy:其次,它可以防止一种形式的脆弱基类失败。有关详细信息,请参阅。@dnkulkarni:编译器选择在编译时调用哪个虚拟方法槽,因此它如何使用编译时类型以外的任何东西?如果要使用运行时类型,请将所有内容键入“动态”。