it-swarm.com.de

Unterschied zwischen Shadowing und Overriding in C #?

Was ist der Unterschied zwischen Shadowing und Overriding einer Methode in C #?

92
Jox

Nun Vererbung ...

angenommen, Sie haben folgende Klassen:

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 Sie dies aufrufen:

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 Klassen. Wenn Sie shadow verwenden, werden die von der Basisklasse zurückgegebenen Werte zurückgegeben, anstatt dem Vererbungsbaum des realen Objekttyps zu folgen.

Code hier ausführen

Hoffe ich mache Sinn :)

144
Stormenet

Shadowing ist eigentlich VB parlance für das, was wir in C # als verstecken bezeichnen würden.

Häufig werden Ausblenden (Shadowing in VB) und Überschreiben als Antwort durch Stormenet angezeigt.

Es wird gezeigt, dass eine virtuelle Methode von einer Unterklasse überschrieben wird, und der Aufruf dieser Methode auch für den Typ der Superklasse oder aus dem Code der Superklasse ruft die Ersetzungsimplementierung aus der Unterklasse auf.

Dann wird eine konkrete Methode angezeigt (eine, die nicht als virtuell oder abstrakt markiert ist), die mit dem Schlüsselwort new ausgeblendet wird, wenn eine Methode mit identischer Signatur für die Unterklasse definiert wird. In diesem Fall ist die neue Implementierung nur für die Unterklasse verfügbar, wenn die Methode für den Superklasse-Typ aufgerufen wird, der die ursprüngliche Implementierung verwendet.

Was jedoch oft übersehen wird, ist, dass es auch möglich ist, eine virtuelle Methode auszublenden.

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.

Beachten Sie, dass DoStuff im obigen Beispiel konkret wird und nicht überschrieben werden kann. Es ist jedoch auch möglich, die Schlüsselwörter virtual und new 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 sich die Überschreibung von C trotz aller beteiligten virtuellen Methoden nicht auf die virtuelle Methode von A auswirkt, da die Implementierung von A durch new in B ausgeblendet wird.

Bearbeiten: In den Kommentaren zu dieser Antwort wurde darauf hingewiesen, dass das oben Gesagte 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 allerlei Schwierigkeiten geraten, wenn Sie auch die Modifikatoren für die Barrierefreiheit ä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 überschreibbar. Alles legal und erklärbar nach .NET-Typregeln, niemals ganz unintuativ.

Ich habe diese Antwort gepostet, um ein besseres Verständnis der Funktionsweise zu erlangen, und nicht um Vorschläge für Techniken zu machen, die frei verwendet werden können.

31
AnthonyWJones

Ich denke, der Hauptunterschied besteht darin, dass Sie beim Shadowing den Namen im Wesentlichen wiederverwenden und die Verwendung der Oberklasse einfach ignorieren. Durch das Überschreiben ändern Sie die Implementierung, jedoch nicht die Zugänglichkeit und Signatur (z. B. Parametertypen und Rückgabe). Siehe http://www.geekinterview.com/question_details/19331 .

6

Shadowing ist ein VB.NET-Konzept. In C # wird Shadowing als Verstecken bezeichnet. Die abgeleitete Klassenmethode wird ausgeblendet. Dies geschieht mit dem Schlüsselwort "new".

Das Schlüsselwort "Override" wird verwendet, um eine vollständig neue Implementierung einer Basisklassenmethode (die mit "Virtual" markiert ist) in der abgeleiteten Klasse bereitzustellen.

5
Ath An

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 für den Typ 'a' erstellt (hier ist der Typ 'A'). Wenn Sie jedoch dieselbe Methode in Klasse B implementieren, die bereits in Klasse A vorhanden ist, wird dies vom Compiler durchgeführt Sie werden gewarnt, ein "neues" Schlüsselwort zu verwenden. Wenn Sie "Neu" verwenden, verschwindet die Warnung. Abgesehen davon gibt es keinen Unterschied zwischen der Verwendung von "Neu" oder der Nichtverwendung in der geerbten Klasse.

In einigen Situationen müssen Sie möglicherweise eine Methode der Referenzklasse aufrufen, die zu diesem Zeitpunkt in der jeweiligen Instanz enthalten ist, anstatt eine Methode für den Objekttyp aufzurufen. Im obigen Fall ist die Referenz 'B', aber der Typ ist 'A'. Wenn der Methodenaufruf also auf 'B' erfolgen soll, verwenden Sie Virtual and override, um dies zu erreichen.

Hoffe das hilft...

Daniel Sandeep.

0
Daniel Sandeep