Przechowywanie wersji przesłonięć i nowych słów kluczowych (Przewodnik programowania w języku C#)Versioning with the Override and New Keywords (C# Programming Guide)

Język Języka C# został zaprojektowany tak, aby przechowywanie wersji między klasami podstawowymi i pochodnymi w różnych bibliotekach może ewoluować i utrzymywać zgodność z poprzednimi wersjami.The C# language is designed so that versioning between base and derived classes in different libraries can evolve and maintain backward compatibility. Oznacza to na przykład, że wprowadzenie nowego elementu członkowskiego w klasie podstawowej o tej samej nazwie jako element członkowski w klasie pochodnej jest całkowicie obsługiwany przez C# i nie prowadzi do nieoczekiwanego zachowania.This means, for example, that the introduction of a new member in a base class with the same name as a member in a derived class is completely supported by C# and does not lead to unexpected behavior. Oznacza to również, że klasa musi jawnie stwierdzić, czy metoda ma zastąpić dziedziczoną metodę, czy też metoda jest nową metodą, która ukrywa metodę dziedziczoną o podobnej nazwie.It also means that a class must explicitly state whether a method is intended to override an inherited method, or whether a method is a new method that hides a similarly named inherited method.

W języku C#klasy pochodne mogą zawierać metody o tej samej nazwie co metody klasy podstawowej.In C#, derived classes can contain methods with the same name as base class methods.

  • Metoda klasy podstawowej musi być zdefiniowana wirtualna.The base class method must be defined virtual.

  • Jeśli metoda w klasie pochodnej nie jest poprzedzona nowymi lub zastąpić słowa kluczowe, kompilator new wyda ostrzeżenie i metoda będzie zachowywać się tak, jakby słowo kluczowe były obecne.If the method in the derived class is not preceded by new or override keywords, the compiler will issue a warning and the method will behave as if the new keyword were present.

  • Jeśli metoda w klasie pochodnej jest new poprzedzona słowem kluczowym, metoda jest definiowana jako niezależna od metody w klasie podstawowej.If the method in the derived class is preceded with the new keyword, the method is defined as being independent of the method in the base class.

  • Jeśli metoda w klasie pochodnej jest override poprzedzona słowem kluczowym, obiekty klasy pochodnej wywoła tę metodę zamiast metody klasy podstawowej.If the method in the derived class is preceded with the override keyword, objects of the derived class will call that method instead of the base class method.

  • Metoda klasy podstawowej można wywołać z poziomu base klasy pochodnej przy użyciu słowa kluczowego.The base class method can be called from within the derived class using the base keyword.

  • Słowa override virtualkluczowe new , i słowa kluczowe mogą być również stosowane do właściwości, indeksatorów i zdarzeń.The override, virtual, and new keywords can also be applied to properties, indexers, and events.

Domyślnie metody Języka C# nie są wirtualne.By default, C# methods are not virtual. Jeśli metoda jest zadeklarowana jako wirtualna, każda klasa dziedzicząca metodę można zaimplementować własną wersję.If a method is declared as virtual, any class inheriting the method can implement its own version. Aby metoda była wirtualna, virtual modyfikator jest używany w deklaracji metody klasy podstawowej.To make a method virtual, the virtual modifier is used in the method declaration of the base class. Klasa pochodna może następnie zastąpić podstawową metodę override wirtualną przy użyciu słowa kluczowego new lub ukryć metodę wirtualną w klasie podstawowej przy użyciu słowa kluczowego.The derived class can then override the base virtual method by using the override keyword or hide the virtual method in the base class by using the new keyword. Jeśli nie override określono słowa new kluczowego ani słowa kluczowego, kompilator wyda ostrzeżenie, a metoda w klasie pochodnej ukryje metodę w klasie podstawowej.If neither the override keyword nor the new keyword is specified, the compiler will issue a warning and the method in the derived class will hide the method in the base class.

Aby zademonstrować to w praktyce, załóżmy przez GraphicsClasschwilę, że firma A utworzyła klasę o nazwie , której używa program.To demonstrate this in practice, assume for a moment that Company A has created a class named GraphicsClass, which your program uses. Oto: GraphicsClassThe following is GraphicsClass:

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

Firma używa tej klasy i używasz jej do uzyskania własnej klasy, dodając nową metodę:Your company uses this class, and you use it to derive your own class, adding a new method:

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

Aplikacja jest używana bez problemów, dopóki firma A GraphicsClassnie wyda nowej wersji , która przypomina następujący kod:Your application is used without problems, until Company A releases a new version of GraphicsClass, which resembles the following code:

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

Nowa wersja GraphicsClass teraz zawiera metodę DrawRectangleo nazwie .The new version of GraphicsClass now contains a method named DrawRectangle. Początkowo nic się nie dzieje.Initially, nothing occurs. Nowa wersja jest nadal binarna kompatybilna ze starą wersją.The new version is still binary compatible with the old version. Każde wdrożone oprogramowanie będzie nadal działać, nawet jeśli nowa klasa jest zainstalowana w tych systemach komputerowych.Any software that you have deployed will continue to work, even if the new class is installed on those computer systems. Wszelkie istniejące wywołania DrawRectangle metody będzie nadal odwoływać się do wersji, w klasie pochodnej.Any existing calls to the method DrawRectangle will continue to reference your version, in your derived class.

Jednak gdy tylko ponownie skompilować aplikację przy użyciu GraphicsClassnowej wersji , otrzymasz ostrzeżenie od kompilatora, CS0108.However, as soon as you recompile your application by using the new version of GraphicsClass, you will receive a warning from the compiler, CS0108. To ostrzeżenie informuje, że należy wziąć DrawRectangle pod uwagę, jak chcesz, aby metoda zachowywała się w aplikacji.This warning informs you that you have to consider how you want your DrawRectangle method to behave in your application.

Jeśli chcesz, aby metoda zastępowała nową metodę override klasy podstawowej, użyj słowa kluczowego:If you want your method to override the new base class method, use the override keyword:

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

Słowo override kluczowe upewnia się, YourDerivedGraphicsClass że wszystkie obiekty pochodzące DrawRectanglez użyje wersji klasy pochodnej .The override keyword makes sure that any objects derived from YourDerivedGraphicsClass will use the derived class version of DrawRectangle. Obiekty pochodzące YourDerivedGraphicsClass z nadal można uzyskać DrawRectangle dostęp do wersji klasy podstawowej za pomocą podstawowego słowa kluczowego:Objects derived from YourDerivedGraphicsClass can still access the base class version of DrawRectangle by using the base keyword:

base.DrawRectangle();

Jeśli nie chcesz, aby metoda zastąpić nową metodę klasy podstawowej, mają zastosowanie następujące zagadnienia.If you do not want your method to override the new base class method, the following considerations apply. Aby uniknąć pomyłek między dwiema metodami, można zmienić nazwę metody.To avoid confusion between the two methods, you can rename your method. Może to być czasochłonne i podatne na błędy, a w niektórych przypadkach po prostu nie praktyczne.This can be time-consuming and error-prone, and just not practical in some cases. Jednak jeśli projekt jest stosunkowo mały, można użyć opcji refaktoryzacji programu Visual Studio, aby zmienić nazwę metody.However, if your project is relatively small, you can use Visual Studio's Refactoring options to rename the method. Aby uzyskać więcej informacji, zobacz Refaktoryzowanie klas i typów (projektant klas).For more information, see Refactoring Classes and Types (Class Designer).

Alternatywnie można zapobiec ostrzeżenie przy new użyciu słowa kluczowego w definicji klasy pochodnej:Alternatively, you can prevent the warning by using the keyword new in your derived class definition:

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

Za new pomocą słowa kluczowego informuje kompilator, że definicja ukrywa definicji, która jest zawarta w klasie podstawowej.Using the new keyword tells the compiler that your definition hides the definition that is contained in the base class. Jest to zachowanie domyślne.This is the default behavior.

Zastępowanie i wybór metodyOverride and Method Selection

Gdy metoda jest nazwany na klasy, kompilator C# wybiera najlepszą metodę do wywołania, jeśli więcej niż jedna metoda jest zgodna z wywołaniem, na przykład, gdy istnieją dwie metody o tej samej nazwie i parametry, które są zgodne z parametrem przekazany.When a method is named on a class, the C# compiler selects the best method to call if more than one method is compatible with the call, such as when there are two methods with the same name, and parameters that are compatible with the parameter passed. Następujące metody byłyby zgodne:The following methods would be compatible:

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

Gdy DoWork jest wywoływana Derivedna wystąpienie , kompilator C# najpierw spróbuje DoWork dokonać Derivedpołączenia zgodne z wersjami zadeklarowane pierwotnie na .When DoWork is called on an instance of Derived, the C# compiler will first try to make the call compatible with the versions of DoWork declared originally on Derived. Metody zastępowania nie są traktowane jako zadeklarowane w klasie, są to nowe implementacje metody zadeklarowanej w klasie podstawowej.Override methods are not considered as declared on a class, they are new implementations of a method declared on a base class. Tylko wtedy kompilator C# nie może dopasować Derived wywołania metody do oryginalnej metody na będzie próbował dopasować wywołanie do metody zastąpione o tej samej nazwie i parametrów zgodnych.Only if the C# compiler cannot match the method call to an original method on Derived will it try to match the call to an overridden method with the same name and compatible parameters. Przykład:For example:

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

Ponieważ zmienna val może zostać przekonwertowana na podwójnie niejawnie, kompilator C# wywołuje DoWork(double) zamiast . DoWork(int)Because the variable val can be converted to a double implicitly, the C# compiler calls DoWork(double) instead of DoWork(int). Istnieją dwa sposoby, aby tego uniknąć.There are two ways to avoid this. Najpierw należy unikać deklarowania nowych metod o takiej samej nazwie jak metody wirtualne.First, avoid declaring new methods with the same name as virtual methods. Po drugie można poinstruować kompilator C# wywołać metodę wirtualną, wykonując wyszukiwanie Derived Baselisty metod klasy podstawowej przez rzutowanie wystąpienia do .Second, you can instruct the C# compiler to call the virtual method by making it search the base class method list by casting the instance of Derived to Base. Ponieważ metoda jest wirtualna, DoWork(int) Derived zostanie wywołana implementacja on.Because the method is virtual, the implementation of DoWork(int) on Derived will be called. Przykład:For example:

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

Aby uzyskać więcej new overrideprzykładów i zobacz Wiedza, kiedy używać zastępowania i nowe słowa kluczowe.For more examples of new and override, see Knowing When to Use Override and New Keywords.

Zobacz teżSee also