Megosztás a következőn keresztül:


Verziószámozás felülbírálással és új kulcsszavakkal (C# programozási útmutató)

A C#-nyelv úgy lett kialakítva, hogy a különböző kódtárak alap- és származtatott osztályai közötti verziószámozás fejlődjön, és fenntarthassa a visszamenőleges kompatibilitást. Ez például azt jelenti, hogy a C# teljes mértékben támogatja egy új tag bevezetését egy alaposztályban, amelynek neve megegyezik egy származtatott osztály tagjával, és nem vezet váratlan viselkedéshez. Azt is jelenti, hogy az osztálynak explicit módon meg kell állapítania, hogy egy metódus egy örökölt metódus felülbírálására szolgál-e, vagy egy metódus egy új metódus, amely elrejt egy hasonlóan elnevezett öröklött metódust.

A C#-ban a származtatott osztályok olyan metódusokat tartalmazhatnak, amelyek neve megegyezik az alaposztály-metódusokkal.

  • Ha a származtatott osztály metódusát nem előzi meg új vagy felülbíráló kulcsszavak, a fordító figyelmeztetést ad ki, és a metódus úgy fog viselkedni, mintha a new kulcsszó jelen lett volna.

  • Ha a származtatott osztály metódusát megelőzi a new kulcsszó, a metódus az alaposztály metódusától függetlenként van definiálva.

  • Ha a származtatott osztály metódusát megelőzi a override kulcsszó, a származtatott osztály objektumai az alaposztály metódusa helyett ezt a metódust hívják meg.

  • Ahhoz, hogy a kulcsszót override a származtatott osztály metódusára alkalmazza, az alaposztály metódusát virtuálisan kell definiálni.

  • Az alaposztály metódusa meghívható a származtatott osztályból a base kulcsszó használatával.

  • A override, virtualés a kulcsszavak tulajdonságokra, indexelőkre és new eseményekre is alkalmazhatók.

Alapértelmezés szerint a C# metódusok nem virtuálisak. Ha egy metódus virtuálisként van deklarálva, a metódust öröklő bármely osztály implementálhatja a saját verzióját. A metódus virtuálissá tételéhez a virtual módosító az alaposztály metódusdeklarációjában használatos. A származtatott osztály ezután felülbírálhatja az alapszintű virtuális metódust a override kulcsszó használatával, vagy elrejtheti a virtuális metódust az alaposztályban a new kulcsszó használatával. Ha sem a override kulcsszó, sem a new kulcsszó nincs megadva, a fordító figyelmeztetést ad ki, és a származtatott osztály metódusa elrejti a metódust az alaposztályban.

Ennek a gyakorlatban való bemutatásához tegyük fel, hogy az A vállalat létrehozott egy osztályt GraphicsClass, amelyet a program használ. A következők:GraphicsClass

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

A vállalat ezt az osztályt használja, ön pedig saját osztályt hoz létre, új metódus hozzáadásával:

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

Az alkalmazás problémamentesen használható, amíg az A vállalat nem ad ki egy új verziót GraphicsClass, amely a következő kódhoz hasonlít:

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

Az új verzió GraphicsClass egy metódust DrawRectangletartalmaz. Kezdetben semmi sem történik. Az új verzió továbbra is binárisan kompatibilis a régi verzióval. Az üzembe helyezett szoftverek továbbra is működni fognak, még akkor is, ha az új osztály telepítve van ezeken a számítógépes rendszereken. A metódushoz DrawRectangle intézett összes meglévő hívás továbbra is hivatkozni fog az Ön verziójára a származtatott osztályban.

Amint azonban az alkalmazás újrafordítása az új verzió GraphicsClasshasználatával történik, figyelmeztetést kap a CS0108 fordítótól. Ez a figyelmeztetés arról tájékoztatja, hogy figyelembe kell vennie, hogyan szeretné, hogy a DrawRectangle metódus az alkalmazásban viselkedjen.

Ha azt szeretné, hogy a metódus felülbírálja az új alaposztály-metódust, használja a következő kulcsszót override :

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

A override kulcsszó gondoskodik arról, hogy a származtatott YourDerivedGraphicsClass objektumok a származtatott osztályverziót DrawRectanglehasználják. A származtatott YourDerivedGraphicsClass objektumok továbbra is hozzáférhetnek az alaposztály verziójához DrawRectangle az alapszintű kulcsszó használatával:

base.DrawRectangle();

Ha nem szeretné, hogy a metódus felülbírálja az új alaposztály-metódust, az alábbi szempontokat kell figyelembe vennie. A két módszer közötti félreértések elkerülése érdekében átnevezheti a metódust. Ez időigényes és hibalehetőséget jelenthet, és bizonyos esetekben nem praktikus. Ha azonban a projekt viszonylag kicsi, a Visual Studio újrabontási beállításaival átnevezheti a metódust. További információ: Osztályok és típusok újrabontása (Osztály Tervező).

Másik lehetőségként megakadályozhatja a figyelmeztetést a származtatott new osztálydefiníció kulcsszójának használatával:

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

new A kulcsszó használatával a fordító közli, hogy a definíció elrejti az alaposztályban található definíciót. Ez az alapértelmezett viselkedés.

Felülbírálás és módszer kiválasztása

Ha egy metódus el van nevezve egy osztályban, a C#-fordító kiválasztja a legjobban meghívható metódust, ha több metódus is kompatibilis a hívással, például ha két azonos nevű metódus van, és az átadott paraméterrel kompatibilis paraméterek. A következő módszerek kompatibilisek lehetnek:

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

Amikor DoWork a rendszer meghív egy példánytDerived, a C#-fordító először megpróbálja kompatibilissé tenni a hívást az eredetileg Deriveddeklarált verziókkalDoWork. A felülbírálási metódusok nem minősülnek osztályon deklaráltnak, hanem egy alaposztályon deklarált metódus új implementációi. Csak akkor, ha a C#-fordító nem tud egyezni egy eredeti metódus Derivedmetódushívásával, akkor megpróbál megegyezni egy felülírt metódussal ugyanazzal a névvel és kompatibilis paraméterekkel. Példa:

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

Mivel a változót val kettős implicit módon lehet konvertálni, a C#-fordító ahelyett DoWork(int)hív megDoWork(double). Ezt kétféleképpen lehet elkerülni. Először is kerülje az új metódusok deklarálását a virtuális metódusokkal azonos néven. Másodszor utasíthatja a C#-fordítót, hogy hívja meg a virtuális metódust úgy, hogy az alaposztály metóduslistájában keres, ha a példányt a következőre BaseállítjaDerived. Mivel a metódus virtuális, a rendszer meghívja DoWork(int)Derived a végrehajtást. Példa:

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

További példákat new és overridepéldákat a Felülbírálás és új kulcsszavak használatának ismerete című témakörben talál.

Lásd még