(又是烦人的问题……)

在询问 this 之前 - (这部分与我的问题有关) - 我得到了答案:



好的。

我有这个代码://.Dump() is like a WriteLine command...

 public class Base
    {
        public void Foo(string strings)  { "1".Dump();}
        public virtual void  Foo(object strings)  { "2".Dump();}
    }

    public class Child : Base
    {

        public override void  Foo(object strings)  { "4".Dump();}
    }

但这段代码:
Child c = new Child();
c.Foo("d");

发出:"1"
可是等等 ...

我们不是说 is reduced to contain only methods from the most derived types: 吗?

Child 有 1 个来自其父亲的函数 public void Foo(string strings) 和一个 NEARER 覆盖函数

那么他为什么选择它的基函数呢?继承的功能是否比覆盖更接近?

它与覆盖在运行时的事实有关吗?

请帮助。

编辑

这种情况怎么办?
public class Base
    {
        public virtual void  Foo(int x)  { "1".Dump();}
    }

    public class Child : Base
    {
        public override void  Foo(int x)  { "2".Dump();}
        public void Foo(object x) { "3".Dump();}
    }

void Main()
{
    Child c = new Child();
    c.Foo(6); //emits "3"
}

最佳答案

这里有两个概念被混淆了,重载和覆盖。重载的概念是为同名函数提供多个签名,并根据该签名 选择一个来调用 。覆盖是在派生类中重新定义方法的概念。

子类是否覆盖其中一个方法定义对于调用哪个函数根本无关紧要,因为它不会更改任一方法的签名。根据定义和构造 覆盖一个方法不能改变它的签名

因此,如果签名未更改,则将针对父类和子类使用完全相同的机制,用于根据签名确定要调用的正确函数。

更新

事实上,正如 Eric Lippert 在 his blog 中指出的那样,还有更多内容。事实证明,如果有一个方法与子类中的重载相匹配,它就不会在基类中查找任何方法。原因是合理的 - 避免破坏性更改 - 但是当您同时拥有基类和子类时,结果有些不合逻辑。

我只能附和 Jon Skeet:“鉴于这种奇怪的情况,我的建议是避免跨越继承边界的重载......至少对于如果你扁平化层次结构可以适用于给定调用的不止一种方法的方法”

关于c# - 派生方法强于 C# 中的覆盖?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10780883/

10-12 07:39
查看更多