微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

看完这篇 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.

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

情况1

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
}

好的.根据文章

“deeper” one will be chosen first,even if it isn’t a “better function. and it doesn’t count the override…

所以它是正确的,程序发出“3”. (执行Foo(对象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,将所有对象更改为int:

案例3

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(对象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)并且他也覆盖了一个方法.

但现在,他选择了父亲的功能……

似乎覆盖只有在完全匹配时才会获胜.

再次,这种情况下的规则是什么?

解决方法

请参阅类型T中名称为N的 member lookup process(在您的案例中,类型为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,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的虚拟void Foo(int x)方法的最多派生实现?是的

override void Foo(int x) // Child

这是被调用的.第三个样本中应用了相同的规则.但是当重写方法删除后剩下两个选项时,最佳选择(由于参数类型)是非虚方法.

原文地址:https://www.jb51.cc/csharp/99328.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐