c# - 在 C# 中跨继承边界重载?

标签 c# .net .net-4.0 clr

看完这篇 article & 那 article - 我很困惑。

它说:

If there are two methods at different levels of the hierarchy, the "deeper" one will be chosen first, even if it isn't a "better function member" for the call.

还有——

It turns out that if you override a base class method in a child class, that doesn't count as declaring it.

现在让我们回到我的问题:

案例一

    public class Base
     {
           public virtual void  Foo(int x)  { "1".Dump();}
     }

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


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

OK.根据文章

"deeper" one will be chosen first, even if it isn't a "better function. and it doesn't count the override...

所以它是正确的,程序发出“3”。 (执行 Foo(object x))

让我们更改行 1 行的顺序:

案例2

          public class Base
         {
                 public virtual void  Foo(int x)  { "1".Dump();}
                 public void Foo(object x) { "3".Dump();} //<line being moved here
         }

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


    void Main()
    {
        Child c = new Child();
        c.Foo(10); //emits 2 !!!!
    }

现在它发出“2”。

现在让我们将所有 int 更改为 object 并将所有 object 更改为 int :

案例三

      public class Base
    {
      public virtual void  Foo(object x)  { "1".Dump();}
      public void Foo(int x) { "3".Dump();} 
    }

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


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

问题:


问题#1:在案例 2 中,Child 从其父亲那里继承了 Foo(object x) 并且他还覆盖了一个方法。

但是我们不就是这么说的吗:

It turns out that if you override a base class method in a child class, that doesn't count as declaring it

???

事实上,我们也没有声明继承函数...所以在这种情况下规则是什么


问题#2:在案例 3 中,Child 从其父亲那里继承了 Foo(int x) 并且他还覆盖了一个方法。

但是现在,他选择了它的父函数....

似乎 override 只有在完全匹配时才会获胜。

再次强调,在这种情况下,规则是什么


最佳答案

参见 member lookup process类型 T 中的名称 N(在您的例子中,类型为 Child 的成员 Foo):

首先,构造在 T 中声明的名为 N 的所有可访问(第 3.5 节)成员和 T 的基本类型(第 7.3.1 节)的集合:

virtual void Foo(int x) // Base
void Foo(object x) // Base
override void Foo(int x) // Child

包含覆盖修饰符的声明被排除在集合之外。

virtual void Foo(int x) // Base
void Foo(object x) // Base

参数具有整数类型。所以,这里最好的选择是(参数类型匹配参数类型)

virtual void Foo(int x) // Base

并且调用了这个方法。但它是虚方法。并且由于 virtual method invocation 而被调用机制:

For every virtual method declared in or inherited by a class, there exists a most derived implementation of the method with respect to that class. The most derived implementation of a virtual method M with respect to a class R is determined as follows:

  • If R contains the introducing virtual declaration of M, then this is the most derived implementation of M.
  • Otherwise, if R contains an override of M, then this is the most derived implementation of M.
  • Otherwise, the most derived implementation of M with respect to R is the same as the most derived implementation of M with respect to the direct base class of R.

关于 Child 类的 virtual void Foo(int x) 方法的大多数派生实现是什么?是的,是的

override void Foo(int x) // Child

被调用。 在您的第三个示例中应用相同的规则。但是,当重写方法删除后留下两个选项时,最佳选择(由于参数类型)是非虚拟方法。

关于c# - 在 C# 中跨继承边界重载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10786300/

相关文章:

c# - 显示重新抛出的异常的堆栈跟踪,而不是从抛出点开始的堆栈跟踪

c# - RegisterStartupScript 和 RegisterClientScriptBlock 的区别?

c# - 任务并行库 - LongRunning 任务与多个 Continuations

wpf - DatePicker DisplayDate 绑定(bind)问题

c# - C#中开启泛型类型继承动态识别

c# - 通过生成包含数字的随机任务来添加数字

c# - 处理多个配置文件实例的最佳方式?

c#-4.0 - CultureInfo.Name 属性的最大长度

c# - 在 C# 中读取一个简单的 XML 配置文件

c# - "Browser"表示哪个平台?