Unterschied zwischen Shadowing und Overriding in C #?

Was ist der Unterschied zwischen dem Spiegeln und Überschreiben einer Methode in C #?

Gut Erbschaft …

Angenommen, Sie haben diese classn:

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 } 

dann wenn du das nennst:

 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 

Angenommen, Sie haben eine Basisklasse und verwenden die Basisklasse in Ihrem gesamten Code anstelle der geerbten classn. Wenn Sie shadow verwenden, werden die von der Basisklasse zurückgegebenen Werte zurückgegeben und nicht die inheritancesstruktur des realen Objekttyps.

Code hier ausführen

Hoffe ich mache Sinn 🙂

Shadowing ist eigentlich der VB-Sprachgebrauch für das, was wir als Verstecken in C # bezeichnen würden.

Oft wird Verbergen (Shadowing in VB) und Overriding wie in Antwort von Stormenet gezeigt .

Es wird gezeigt, dass eine virtuelle Methode von einer Unterklasse überschrieben wird und Aufrufe an diese Methode selbst für den Superklasse-Typ oder aus dem Inside-Code der Superklasse die Ersatzimplementierung von der Unterklasse aufrufen.

Dann wird eine konkrete Methode angezeigt (eine, die nicht als virtuell oder abstrakt markiert ist), die durch Verwendung des new Schlüsselworts bei der Definition einer Methode mit identischer Signatur in der Unterklasse ausgeblendet wird. In diesem Fall, wenn die Methode für den Super-Class-Typ aufgerufen wird, wird die ursprüngliche Implementierung verwendet, die neue Implementierung ist nur für die Unterklasse verfügbar.

Was jedoch häufig übersehen wird, ist, dass es auch möglich ist, eine virtuelle Methode zu verstecken.

 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. 

Hinweis: Im obigen Beispiel wird DoStuff konkreter und kann nicht überschrieben werden. Es ist jedoch auch möglich, sowohl die virtual als auch die new Keywords zusammen zu verwenden.

 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. 

Beachten Sie, dass trotz der Tatsache, dass alle beteiligten Methoden virtuell sind, sich die Überschreibung auf C nicht auf die virtuelle Methode in A auswirkt, da in B die new Implementierung verwendet wird.

Edit: In den Kommentaren zu dieser Antwort wurde angemerkt, dass das Obige gefährlich oder zumindest nicht besonders nützlich sein kann. Ich würde sagen, ja, es kann gefährlich sein und wäre da draußen, wenn es überhaupt nützlich wäre.

Insbesondere könnten Sie in alle möglichen Schwierigkeiten geraten, wenn Sie auch die Zugriffsmodifikatoren ändern. Beispielsweise:-

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

Für einen externen Erben von Bar bleibt Foos Implementierung von Thing () zugänglich und übersteuerbar. Alle legalen und erklärbar nach .NET-Regeln sind nie völlig unintuativ.

Ich habe diese Antwort gepostet, um das Verständnis dafür zu vertiefen, dass die Dinge nicht als Anregung für Techniken dienen, die frei verwendet werden können.

Ich denke, der Hauptunterschied besteht darin, dass du mit dem Shadowing im Wesentlichen den Namen wieder verwendest und nur die Verwendung der Superklasse ignorierst. Beim Überschreiben ändern Sie die Implementierung, aber nicht die Erreichbarkeit und die Signatur (z. B. Parametertypen und Rückgabe). Siehe http://www.geekinterview.com/question_details/19331 .

Shadowing ist ein VB.NET-Konzept. In C # ist Shadowing als Verstecken bekannt. Es verbirgt die abgeleitete classnmethode. Dies wird mit dem Schlüsselwort ‘new’ erreicht.

Override-Schlüsselwort wird verwendet, um eine vollständig neue Implementierung einer Basisklassenmethode (die mit “Virtual” gekennzeichnet ist) in der abgeleiteten class bereitzustellen.

Grundsätzlich, wenn Sie etwas wie unten haben,

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

Jede Methode, die Sie für das Objekt ‘a’ aufrufen, wird mit dem Typ ‘a’ ausgeführt (Hier ist der Typ ‘A’). Wenn Sie jedoch dieselbe Methode in class B implementieren, die bereits in class A vorhanden ist, wird der Compiler warnt Sie, ein “Neues” Schlüsselwort zu verwenden. Wenn Sie “Neu” verwenden, wird die Warnung ausgeblendet. Ansonsten gibt es keinen Unterschied zwischen der Verwendung von “Neu” oder der Nichtverwendung in der geerbten class.

In einigen Situationen müssen Sie möglicherweise eine Methode der Referenzklasse aufrufen, die die bestimmte Instanz zu diesem Zeitpunkt enthält, anstatt eine Methode für den Objekttyp aufzurufen. Im obigen Fall ist der Verweis “B”, aber der Typ ist “A”. Wenn Sie möchten, dass der Methodenaufruf auf “B” erfolgt, verwenden Sie Virtual und Override, um dies zu erreichen.

Hoffe das hilft…

Daniel Sandeep.