【问题标题】:Polymorphic method runs twice when called only once [duplicate]多态方法在仅调用一次时运行两次[重复]
【发布时间】:2014-08-15 02:33:23
【问题描述】:

这是基于另一个我非常喜欢的关于多态性的 SO 问题。所以我玩弄它并修改它以理解它。但后来它扰乱了我对多态的理解。

我在一个类中创建了一个接口,创建了一个类“A”并实现了接口方法。我还创建了另一个扩展“A”的类“B”。还有另一个扩展“B”的“C”类。

当你运行它时,输出是:

BA-> AEP

注意BA-> 部分来自B : A 类,而AEPA : E 中不同方法的默认参数

我在做的时候怎么调用了两个方法

`A instance = new C();
Console.WriteLine(instance.GetName());`

为什么?

    class Program
{
    interface E
    {
        string GetName(string s);

    }

    public class A : E
    {

        public virtual string GetName(string s="AEP")
        {
            return s;
        }
    }

    public class B : A
    {
        public override string GetName(string s="BAP")
        {
            return "BA-> " + s;
        }
    }

    public class C : B
    {
        public new string GetName()
        {
            return "CB->";
        }
    }

    static void Main()
    {
        A instance = new C();
        Console.WriteLine(instance.GetName());
        Console.ReadLine();
    }
}

【问题讨论】:

  • return s改成return s + "bla",你会发现它只是默认参数
  • 这基本上是 2 个问题的重复 - 一个 C# optional parameters on overridden methods 涵盖了为什么显示“AEP”,C# keyword usage virtual+override vs. new 解释了为什么根本不调用 C.GetName(因此是“BA->”部分输出)。如果这些链接不足以澄清问题,请发表评论。
  • @Zuzlx 因为你从不在你的Main 中使用B
  • 是的。谢谢大家!

标签: c# polymorphism


【解决方案1】:

该方法不会被调用两次。您看到的是来自B 的覆盖版本被调用,因为运行时实例是C。但是,因为静态类型是A,所以您使用A 定义的方法的默认参数值。默认参数是在调用站点插入的编译时功能,因此它不考虑被覆盖方法的值。

【讨论】:

  • 谢谢。很高兴知道否则会有一些有趣的错误。
【解决方案2】:

您在这里使用默认参数,这是纯语法糖,并在编译时根据您使用的类方法解析。

    A instance = new C();
    Console.WriteLine(instance.GetName());

由于没有没有参数的GetName() 方法,编译器使用默认参数值并使用A 类中的声明(编译时已知的变量)作为GetName("AEP") 进行编译。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-15
    • 2017-11-05
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 2017-09-24
    • 1970-01-01
    相关资源
    最近更新 更多