当前位置:  开发笔记 > 编程语言 > 正文

C#中的阴影和覆盖之间的区别?

如何解决《C#中的阴影和覆盖之间的区别?》经验,为你挑选了4个好方法。

阴影覆盖 C#中的方法有什么区别?



1> Stormenet..:

继承良好......

假设你有这个类:

class A {
   public int Foo(){ return 5;}
   public virtual int Bar(){return 5;}
}
class B : A{
   public new int Foo() { return 1;}     //shadow
   public override int Bar() {return 1;} //override
}

然后你打电话给这个:

A clA = new A();
B clB = new B();

Console.WriteLine(clA.Foo()); // output 5
Console.WriteLine(clA.Bar()); // output 5
Console.WriteLine(clB.Foo()); // output 1
Console.WriteLine(clB.Bar()); // output 1

//now let's cast B to an A class
Console.WriteLine(((A)clB).Foo()); // output 5 <<<-- shadow
Console.WriteLine(((A)clB).Bar()); // output 1

假设您有一个基类,并且在所有代码中使用基类而不是继承的类,并且使用shadow,它将返回基类返回的值,而不是跟随对象的实际类型的继承树.

在这里运行代码

希望我有意义:)


覆盖提供多态性,阴影在层次结构的该级别提供不同的实现,但不是多态的.
@AnthonyWJones,Polymorphism是一种(派生)类型用作不同(基础)类型的能力,其中真实实现(行为)是真实特定(派生)类型的实现.如果覆盖,派生方法将通过对base的引用进行调用,但如果你的影子不是真的
在我看来,您的示例代码中有错误.铸造应该是((A)clB).Foo(),不应该吗?

2> AnthonyWJone..:

阴影实际上就是我们所谓的隐藏在C#中的VB用语.

经常隐藏(在VB中隐藏)和覆盖在Stormenet的回答中显示.

虚拟方法被子类覆盖,并且即使在超类类型上调用该方法,或者从超类的内部代码调用该方法也将从子类调用替换实现.

然后,new在定义子类上具有相同签名的方法时,通过使用关键字隐藏一个具体方法(一个未标记为虚拟或抽象的方法).在这种情况下,当在超类类型上调用该方法时,使用原始实现,新实现仅在子类上可用.

然而,经常遗漏的是,也可以隐藏虚拟方法.

class A
{
    public virtual void DoStuff() { // original implementation }
}

class B : A
{
    public new void DoStuff() {  //new implementation }
}

B b = new B();
A a = b;

b.DoStuff(); //calls new implementation
a.DoStuff(); //calls original implementation.

请注意,在上面的示例中,DoStuff变得具体,无法覆盖.但是,也可以同时使用virtualnew关键字.

class A
{
    public virtual void DoStuff() { // original implementation }
}

class B : A
{
    public new virtual void DoStuff() {  //new implementation }
}

class C : B
{
    public override void DoStuff() { //replacement implementation }
}

C c = new C();
B b = c;
A a = b;

c.DoStuff(); //calls replacement implementation
b.DoStuff(); //calls replacement implementation
a.DoStuff(); //calls original implementation.

请注意,尽管所涉及的所有方法都是虚拟的,但C上的覆盖不会影响A上的虚方法,因为new在B中使用隐藏了A实现.

编辑:在对这个答案的评论中已经注意到上述内容可能是危险的,或者至少不是特别有用.我会说是的它可能是危险的,如果它有用的话就会在那里.

特别是如果你也改变了可访问性修饰符,你可能会遇到各种各样的麻烦.例如:-

public class Foo
{
    internal Foo() { }
    protected virtual string Thing() { return "foo"; }
}

public class Bar : Foo
{
 internal new string Thing() { return "bar"; }
}

对于外部继承者来说Bar,FooThing()的实现仍然是可访问和可覆盖的.根据.NET类型规则,所有合法且可解释的内容都是毫不含糊的.

我发布了这个答案,以加深对事物如何工作的理解,而不是作为可以自由使用的技术的建议.


可用性?你的意思是有用吗?在您需要它们之前,边缘上的某些东西可能看起来毫无用处.
很高兴知道.尽管它的使用可能很危险:)
如果使用不当,所有工具都可能存在危险.

3> Matthew Flas..:

我认为主要区别在于,使用阴影,你实际上是在重用名称,而忽略了超类的使用.通过覆盖,您将更改实现,但不会更改可访问性和签名(例如参数类型和返回).见http://www.geekinterview.com/question_details/19331.



4> Shezi..:

阴影是VB.NET概念。在C#中,阴影称为隐藏。它隐藏了派生类方法。使用“ new”关键字即可完成。

Override关键字用于在派生类中提供基类方法(标记为“虚拟”)的全新实现。

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有