Freigeben über


Versionsverwaltung mit den Schlüsselwörtern "override" und "new" (C#-Programmierhandbuch)

Die C#-Sprache ist so konzipiert, dass die Versionsverwaltung zwischen Basis - und abgeleiteten Klassen in verschiedenen Bibliotheken sich weiterentwickeln und die Abwärtskompatibilität beibehalten kann. Dies bedeutet beispielsweise, dass die Einführung eines neuen Elements in einer Basisklasse mit demselben Namen wie ein Mitglied in einer abgeleiteten Klasse vollständig von C# unterstützt wird und nicht zu unerwartetem Verhalten führt. Dies bedeutet auch, dass eine Klasse explizit angeben muss, ob eine Methode eine geerbte Methode außer Kraft setzen soll oder ob es sich bei einer Methode um eine neue Methode handelt, die eine ähnlich benannte geerbte Methode ausblendet.

In C# können abgeleitete Klassen Methoden mit demselben Namen wie Basisklassenmethoden enthalten.

  • Wenn der Methode in der abgeleiteten Klasse keine new- oder override-Schlüsselwörter vorangestellt werden, gibt der Compiler eine Warnung aus, und die Methode verhält sich so, als ob das new-Schlüsselwort vorhanden wäre.

  • Wenn der Methode in der abgeleiteten Klasse das new Schlüsselwort vorangestellt ist, wird die Methode als unabhängig von der Methode in der Basisklasse definiert.

  • Wenn der Methode in der abgeleiteten Klasse das override Schlüsselwort vorangestellt ist, rufen Objekte der abgeleiteten Klasse diese Methode anstelle der Basisklassenmethode auf.

  • Um das override Schlüsselwort auf die Methode in der abgeleiteten Klasse anzuwenden, muss die Basisklassenmethode virtuell definiert werden.

  • Die Basisklassenmethode kann mithilfe des base Schlüsselworts aus der abgeleiteten Klasse aufgerufen werden.

  • Die override, virtualund new Schlüsselwörter können auch auf Eigenschaften, Indexer und Ereignisse angewendet werden.

C#-Methoden sind standardmäßig nicht virtuell. Wenn eine Methode als virtuell deklariert wird, kann jede Klasse, die die Methode erbt, eine eigene Version implementieren. Um eine Methode virtuell zu machen, wird der virtual Modifizierer in der Methodendeklaration der Basisklasse verwendet. Die abgeleitete Klasse kann dann die virtuelle Basismethode mithilfe des override Schlüsselworts überschreiben oder die virtuelle Methode in der Basisklasse mithilfe des new Schlüsselworts ausblenden. Wenn weder das override Schlüsselwort noch das new Schlüsselwort angegeben wird, gibt der Compiler eine Warnung aus, und die Methode in der abgeleiteten Klasse blendet die Methode in der Basisklasse aus.

Um dies in der Praxis zu veranschaulichen, gehen Sie für einen Moment davon aus, dass Company A eine Klasse mit dem Namen GraphicsClasserstellt hat, die Ihr Programm verwendet. Die folgende Datei ist GraphicsClass:

class GraphicsClass
{
    public virtual void DrawLine() { }
    public virtual void DrawPoint() { }
}

Ihr Unternehmen verwendet diese Klasse, und Sie verwenden sie, um Ihre eigene Klasse abzuleiten und eine neue Methode hinzuzufügen:

class YourDerivedGraphicsClass : GraphicsClass
{
    public void DrawRectangle() { }
}

Ihre Anwendung wird ohne Probleme verwendet, bis Firma A eine neue Version von GraphicsClass herausgibt, die dem folgenden Code ähnelt:

class GraphicsClass
{
    public virtual void DrawLine() { }
    public virtual void DrawPoint() { }
    public virtual void DrawRectangle() { }
}

Die neue Version von GraphicsClass jetzt enthält eine Methode mit dem Namen DrawRectangle. Zunächst tritt nichts auf. Die neue Version ist weiterhin binärkompatibel mit der alten Version. Jede von Ihnen bereitgestellte Software funktioniert weiterhin, auch wenn die neue Klasse auf diesen Computersystemen installiert ist. Alle vorhandenen Aufrufe der Methode DrawRectangle verweisen weiterhin auf Ihre Version in der abgeleiteten Klasse.

Sobald Sie die Anwendung jedoch mit der neuen Version von GraphicsClass"Neukompilieren" erneut kompilieren, erhalten Sie eine Warnung vom Compiler CS0108. Diese Warnung informiert Sie darüber, dass Sie überlegen müssen, wie sich Ihre DrawRectangle Methode in Ihrer Anwendung verhalten soll.

Wenn Die Methode die neue Basisklassenmethode außer Kraft setzen soll, verwenden Sie das override Schlüsselwort:

class YourDerivedGraphicsClass : GraphicsClass
{
    public override void DrawRectangle() { }
}

Das Schlüsselwort override stellt sicher, dass alle von YourDerivedGraphicsClass abgeleiteten Objekte die Version von DrawRectangle der abgeleiteten Klasse verwenden. Von YourDerivedGraphicsClass objekten abgeleitete Objekte können weiterhin mithilfe des Basisschlüsselworts auf die Basisklassenversion DrawRectangle zugreifen:

base.DrawRectangle();

Wenn Sie nicht möchten, dass Ihre Methode die neue Basisklassenmethode außer Kraft setzt, gelten die folgenden Überlegungen. Um Verwirrung zwischen den beiden Methoden zu vermeiden, können Sie die Methode umbenennen. Dies kann zeitaufwendig und fehleranfällig sein und ist in einigen Fällen nicht praktikabel. Wenn Ihr Projekt jedoch relativ klein ist, können Sie die Umgestaltungsoptionen von Visual Studio verwenden, um die Methode umzubenennen. Weitere Informationen finden Sie unter "Umgestalten von Klassen und Typen (Klassen-Designer)".

Alternativ können Sie die Warnung mithilfe des Schlüsselworts new in der abgeleiteten Klassendefinition verhindern:

class YourDerivedGraphicsClass : GraphicsClass
{
    public new void DrawRectangle() { }
}

Mithilfe des new Schlüsselworts wird dem Compiler mitgeteilt, dass die Definition die definition ausblendet, die in der Basisklasse enthalten ist. Dies ist das Standardverhalten.

Überschreiben und Methodenauswahl

Wenn eine Methode für eine Klasse benannt wird, wählt der C#-Compiler die beste Methode aus, die aufgerufen werden soll, wenn mehrere Methoden mit dem Aufruf kompatibel sind, z. B. wenn zwei Methoden mit demselben Namen vorhanden sind, und Parameter, die mit dem übergebenen Parameter kompatibel sind. Die folgenden Methoden wären kompatibel:

public class Derived : Base
{
    public override void DoWork(int param) { }
    public void DoWork(double param) { }
}

Wenn DoWork auf einer Instanz von Derived aufgerufen wird, versucht der C#-Compiler zunächst, den Aufruf mit den ursprünglich auf DoWork deklarierten Versionen von Derived kompatibel zu machen. Überschreibungsmethoden werden nicht als zur Klasse gehörig betrachtet, sondern als neue Implementierungen einer Methode, die für eine Basisklasse deklariert ist. Nur wenn der C#-Compiler den Methodenaufruf einer Originalmethode nicht mit Derived übereinstimmen kann, wird er versuchen, den Aufruf einer überschriebenen Methode mit demselben Namen und kompatiblen Parametern abzugleichen. Beispiel:

int val = 5;
Derived d = new();
d.DoWork(val);  // Calls DoWork(double).

Da die Variable val implizit in einen double konvertiert werden kann, ruft der C#-Compiler DoWork(double) statt DoWork(int) auf. Es gibt zwei Möglichkeiten, dies zu vermeiden. Vermeiden Sie zunächst, neue Methoden mit demselben Namen wie virtuelle Methoden zu deklarieren. Zweitens können Sie den C#-Compiler anweisen, die virtuelle Methode aufzurufen, indem Sie die Instanz von Derived in Base umwandeln, damit die Liste der Methoden der Basisklasse durchsucht wird. Da es sich um eine virtuelle Methode handelt, wird die Implementierung von DoWork(int) auf Derived aufgerufen. Beispiel:

((Base)d).DoWork(val);  // Calls DoWork(int) on Derived.

Weitere Beispiele für new und override finden Sie unter Wann müssen die Schlüsselwörter „override“ und „new“ verwendet werden?.

Siehe auch