为了账号安全,请及时绑定邮箱和手机立即绑定

什么是阴影?

/ 猿问

什么是阴影?

C#
万千封印 2019-11-15 12:32:54

在C#中,“ 阴影 ”一词是什么意思?我已经阅读了此链接,但并没有完全理解它。


查看完整描述

3 回答

?
慕函数4003404

阴影隐藏了基类中的方法。使用您链接的问题中的示例:


class A 

{

   public int Foo(){ return 5;}

   public virtual int Bar(){return 5;}

}

class B : A

{

   public new int Foo() { return 1;}

   public override int Bar() {return 1;}

}

类B 重写虚拟方法Bar。它隐藏(遮盖了)非虚拟方法Foo。替代使用override关键字。阴影是通过new关键字完成的。


在上面的代码中,如果在class中定义方法时未使用new关键字,则会收到以下编译器警告:FooB


'test.B.Foo()' hides inherited member 'test.A.Foo()'. Use the new keyword if hiding was intended.


查看完整回答
反对 回复 2019-11-15
?
交互式爱情

假设我有一个实现虚拟方法的基类:


public class A

{

    public virtual void M() { Console.WriteLine("In A.M()."); }

}

我也有一个派生类,它也定义了方法M:


public class B : A

{

    // could be either "new" or "override", "new" is default

    public void M() { Console.WriteLine("In B.M()."); }

}

现在,假设我编写了这样的程序:


A alpha = new B(); // it's really a B but I cast it to an A

alpha.M();

对于我希望如何实现,我有两种选择。默认行为是调用A的M版本。(这与将new”关键字应用到的行为相同B.M())。


当从基类中调用具有相同名称但行为不同的方法时,这称为“阴影”。


或者,我们可以在上指定“ override” B.M()。在这种情况下,alpha.M()本应称为B的M版本。


查看完整回答
反对 回复 2019-11-15
?
qq_笑_17

重影包括在子类中隐藏具有新定义的基类方法。

隐藏和覆盖之间的区别与方法的调用方式有关。

这样,当虚拟方法被覆盖时,基类的方法调用表的调用地址将替换为子例程的地址。

另一方面,当隐藏方法时,会将新地址添加到子类的方法调用表中。

调用相关方法时:

  1. 获得方法调用表类的类型,如果调用基类的引用,则获得基类的方法表;如果有对子类的引用,则获得子类的方法表。

  2. 在表中搜索该方法,如果找到该方法,则会进行调用,否则将搜索基类方法表。

如果我们使用对子类的引用来调用该方法,则其行为是相同的;如果该方法已被覆盖,则将在基类中找到该方法的地址;如果该方法被隐藏,则将在该类上找到该方法的地址。子类,并且由于已经找到,因此将不会搜索基类表。

如果我们使用对基类的引用来调用该方法,则行为会改变。覆盖时,由于方法地址覆盖了基类条目,因此即使保持对基类的引用,我们也将调用子方法。带有阴影,基类方法表(在我们拥有对基类的引用时,这是唯一可见的表)包含虚拟方法地址,因此将调用基类方法。

通常,阴影是个坏主意,因为它会根据我们对实例的引用而导致实例行为的差异。


查看完整回答
反对 回复 2019-11-15

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信