zárt (C#-referencia)

A C# 15-től kezdve alkalmazhatja a closed módosítót egy osztályra egy zárt hierarchia deklarálásához. Közvetlen altípust csak a deklaráló szerelvényen belüli zárt osztályból származtathat. Mivel a közvetlen leszármazottak készlete rögzített, az switch egyes közvetlen leszármazottakat kezelő kifejezés kimeríti a zárt alaptípust, és nincs szükség alapértelmezett karra.

// Assembly 1
public closed record class JobStatus;
public record class Queued : JobStatus;
public record class Running(int PercentComplete) : JobStatus;
public record class Completed(TimeSpan Elapsed) : JobStatus;
public record class Failed(string Error) : JobStatus;

// Assembly 2
public record class Paused : JobStatus; // Error: 'JobStatus' is a closed class

Ugyanez a gyülekezési korlátozás csak a zárt osztály közvetlen leszármazottaira vonatkozik. A bezárt osztályból származó osztály önmagában nem zárt, kivéve, ha ön is megjelöli.closed Mivel Failed az előző példában egy egyszerű rekord van, egy másik szerelvény származhat belőle:

// Assembly 2
public record class RetryableFailed(string Error, int Attempts) : Failed(Error); // OK: 'Failed' isn't sealed or closed

Ha meg szeretné akadályozni a származtatást Failed is, deklarálja vagy sealedclosed.

A C# nyelv referenciadokumentuma a C# nyelv legújabb kiadású verzióját ismerteti. Emellett a közelgő nyelvi kiadás nyilvános előzetes verziójú funkcióinak kezdeti dokumentációját is tartalmazza.

A dokumentáció azonosítja azokat a funkciókat, amelyeket először a nyelv utolsó három verziójában vagy az aktuális nyilvános előzetes verziókban vezetnek be.

Tip

Ha meg szeretné tudni, hogy mikor jelent meg először egy funkció a C#-ban, tekintse meg a C# nyelvi verzióelőzményeiről szóló cikket.

Note

closed egy környezetfüggő kulcsszó. Különleges jelentése csak akkor van, ha módosítóként jelenik meg egy osztálydeklaráción. Más környezetekben továbbra is használhatja closed azonosítóként. Ha azonosítóként kell használnia closed egy olyan helyzetben, ahol a módosító is érvényes lenne, akkor előtagként @ (például ) meg kell adnia a fordítónak, @closedhogy a módosító helyett azonosítóként kezelje.

Deklarációs szabályok

A closed módosító egy osztálymódosító:

  • Az closed osztály implicit módon abstractvan. Nem kombinálható closedsealeda , staticvagy explicit abstract módosítóval.
  • Egy zárt osztály közvetlen altípusát ugyanabban a szerelvényben és modulban kell deklarálnia, mint a zárt alaposztályt.
  • A zárt osztályból származó osztály önmagában nem zárt. Alkalmazza ismét a closed módosítót, ha azt szeretné, hogy egy származtatott osztály is bezáruljon.

Ha egy általános osztály közvetlenül egy closed osztályból származik, a származtatott osztály minden típusparaméterét az alaposztály specifikációjában kell használni. Ez a szabály nem magáról a closed módosítóról szól: a zárt építésű típus olyan általános típus, amelynek típusargumentumai teljes mértékben meg vannak adva (például ), szemben egy nyitott típussal, példáulTree<T>Tree<int>. A szabály biztosítja, hogy az alaposztály minden zárt, konstruktált típusa pontosan egy zárt, konstruktált típussal rendelkezik a közvetlen leszármazottai között, így a fordító a teljesség okát is meg tudja indokolni.

public closed record class Tree<T>;

public record class Leaf<T>(T Value) : Tree<T>;                       // OK: 'T' appears in the base class
public record class Branch<T>(Tree<T> Left, Tree<T> Right) : Tree<T>; // OK: 'T' appears in the base class
public record class Constant<U>(U Value) : Tree<int> { } // Error: 'U' isn't used in the base class

Teljes körű kapcsolókifejezések

Amikor egy switch kifejezés egy zárt osztály minden közvetlen leszármazottját kezeli, a fordító kimerítőnek tekinti a kapcsolót, és nem generál teljességi figyelmeztetést:

public static string Describe(JobStatus status) => status switch
{
    Queued => "waiting to start",
    Running(var percent) => $"{percent}% complete",
    Completed(var elapsed) => $"finished in {elapsed.TotalSeconds:F1}s",
    Failed(var error) => $"failed: {error}",
    // No warning: every direct descendant of 'JobStatus' is handled.
};

Ha a kapcsolót szabályozó kifejezés null értékű, null akkor a kapcsolónak egy másik lehetséges értékévé válik, amelyet a kapcsolónak kezelnie kell. Az átkapcsolás JobStatus? csak akkor teljes körű, ha a következőket is tartalmazza null:

public static string DescribeOrUnknown(JobStatus? status) => status switch
{
    null => "unknown",
    Queued => "waiting to start",
    Running(var percent) => $"{percent}% complete",
    Completed(var elapsed) => $"finished in {elapsed.TotalSeconds:F1}s",
    Failed(var error) => $"failed: {error}",
    // No warning: every direct descendant of 'JobStatus' is handled, and null is handled.
};

Ha kihagyja a null kart, a fordító figyelmezteti, hogy a minta null nem lesz kezelve. Ugyanez a szabály érvényes arra, hogy a zárt típus egy osztály vagy egy null értékű típusra emelt szerkezet.

További információ arról, hogy a fordító hogyan határozza meg a teljességet, beleértve azt is, hogy a zárt hierarchiák hogyan működnek együtt az általános korlátozásokkal és az akadálymentességgel, lásd a zárt hierarchia mintáit.

Zárt típusra korlátozott típusparaméterek

A zárt osztályra korlátozott típusparamétereket a teljesség ellenőrzéséhez ez a zárt osztály kezeli. Az switch olyan kifejezés, amelynek szabályozási értéke rendelkezik ilyen típusú paraméterrel, teljes körű, ha a zárt kényszer minden közvetlen leszármazottját kezeli:

public static string DescribeJob<X>(X status) where X : JobStatus => status switch
{
    Queued => "waiting to start",
    Running(var percent) => $"{percent}% complete",
    Completed(var elapsed) => $"finished in {elapsed.TotalSeconds:F1}s",
    Failed(var error) => $"failed: {error}",
    // No warning: 'X' is constrained to a closed type, so its direct descendants exhaust the switch.
};

Ez a szabály arra vonatkozik, hogy a típusparaméter megjelenik-e egy metóduson vagy a benne található típuson.

C# nyelvspecifikáció

További információkért tekintse meg a Zárt hierarchiák funkció specifikációját.

Lásd még