在C#中阴影和重写之间的区别?

在C#中阴影重写方法有什么区别?

那么inheritance…

假设你有这个类:

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 

假设你有一个基类,并且在所有代码中使用基类而不是inheritance类,并且使用shadow,它将返回基类返回的值,而不是跟随对象的实际types的inheritance树。

在这里运行代码

希望我有道理:)

阴影实际上是VB的说法,我们将其称为隐藏在C#中。

经常隐藏(在VB中的阴影)和重写显示在Stormenet的答案。

虚拟方法被显示为被子类覆盖,并且即使在超类types或从超类的内部代码中调用该方法也将从子类调用replace实现。

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

但是常常会漏掉的是,隐藏一个虚拟的方法也是可能的。

 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变成具体的,不能被覆盖。 但是也可以同时使用virtual关键字和new关键字。

 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. 

请注意,尽pipe涉及的所有方法都是虚拟的,但C上的重写并不会影响A上的虚方法,因为B中使用了new来隐藏A实现。

编辑:它在这个答案的评论中指出,上述可能是危险的,至less不是特别有用。 我会说是的,它可能是危险的,如果它在所有有用的将在那里。

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

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

Bar的外部inheritance者而言, Foo对Thing()的实现仍然是可以被覆盖的。 根据.NETtypes规则,所有合法和可解释的东西都是非常不直观的。

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

我认为主要的区别在于,在阴影中,你基本上重用了这个名字,而忽略了超类的使用。 重写,你改变了实现,但不是可访问性和签名(例如参数types和返回)。 见http://www.geekinterview.com/question_details/19331

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

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

基本上如果你有像下面这样的东西,

 Class A { } Class B:A { } A a = new B(); 

你在对象“a”上调用的任何方法都将在'a'types(这里的types是'A')上进行。但是如果你在类A中已经存在的类B中实现相同的方法,编译器将会给你一个警告,使用“新”关键字。 如果您使用“新build”,警告将消失。 除此之外,在使用“新build”或不在inheritance的类中使用它们之间没有区别。

在某些情况下,您可能需要调用特定实例在此时保持的引用类的方法,而不是在对象types上调用方法。 在上面的情况下,它所保持的参考是'B',但是types是'A'。 所以,如果你想方法调用应该发生在'B',那么你使用虚拟和覆盖来实现这一点。

希望这可以帮助…

Daniel Sandeep。