Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Počínaje jazykem C# 15 můžete modifikátor použít closed u třídy a deklarovat uzavřenou hierarchii. Přímou podtyp lze odvodit pouze z uzavřené třídy v rámci deklarujícího sestavení. Vzhledem k tomu, že je sada přímých potomků pevná, výraz, switch který zpracovává jednotlivé přímé potomky, vyčerpá uzavřený základní typ a nepotřebuje výchozí arm.
// 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
Omezení stejného sestavení se vztahuje pouze na přímé potomky uzavřené třídy. Třída odvozená z uzavřené třídy není sama o sobě uzavřena, pokud ji closedtaké neoznačíte . Vzhledem k tomu, že Failed v předchozím příkladu je prostý záznam, může z něj odvozeno jiné sestavení:
// Assembly 2
public record class RetryableFailed(string Error, int Attempts) : Failed(Error); // OK: 'Failed' isn't sealed or closed
Pokud chcete zabránit odvození Failed také, deklarujte jej jako sealed nebo closed.
Referenční dokumentace jazyka C# dokumentuje naposledy vydané verze jazyka C#. Obsahuje také počáteční dokumentaci k funkcím ve verzi Public Preview pro nadcházející jazykovou verzi.
Dokumentace identifikuje všechny funkce, které byly poprvé představeny v posledních třech verzích jazyka nebo v aktuálních verzích Public Preview.
Tip
Informace o tom, kdy byla funkce poprvé představena v jazyce C#, najdete v článku o historii verzí jazyka C#.
Note
closed je kontextové klíčové slovo. Má zvláštní význam pouze tehdy, když se zobrazí jako modifikátor v deklaraci třídy. V jiných kontextech můžete dál používat closed jako identifikátor. Pokud potřebujete použít closed jako identifikátor v pozici, kde by modifikátor byl také platný, předpona ho @ předponou (například) informovat kompilátor, @closedaby s ním zachází jako s identifikátorem, a ne jako s modifikátorem.
Pravidla deklarace
closed Modifikátor je modifikátor třídy:
- Třída
closedje implicitněabstract. Nelze kombinovatclosedssealed,staticnebo explicitníabstractmodifikátor. - Je nutné deklarovat přímý podtyp uzavřené třídy ve stejném sestavení a modulu jako uzavřená základní třída.
- Třída odvozená z uzavřené třídy není sama o sobě uzavřená.
closedModifikátor znovu použijte, pokud chcete, aby byla také uzavřena odvozená třída.
Je-li obecná třída přímo odvozena od closed třídy, musí být každý parametr typu v odvozené třídě použit ve specifikaci základní třídy. Toto pravidlo není o samotném modifikátoru closed : uzavřený konstruovaný typ je obecný typ, jehož argumenty typu jsou plně zadané (například Tree<int>), na rozdíl od otevřeného typu jako Tree<T>. Pravidlo zajišťuje, že každý uzavřený vytvořený typ základní třídy má přesně jeden odpovídající uzavřený konstruovaný typ mezi jeho přímými potomky, takže kompilátor může zdůvodnět úplnost.
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
Vyčerpávající výrazy přepínače
switch Když výraz zpracovává všechny přímé potomky uzavřené třídy, kompilátor považuje přepínač za vyčerpávající a nevygeneruje upozornění na neúpatrnost:
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.
};
Pokud je výraz řízení přepínače null, stane se další možnou hodnotou, null kterou musí přepínač zpracovat. Přepnutí JobStatus? je vyčerpávající pouze v případech, kdy zahrnuje 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.
};
Pokud ho null vynecháte, kompilátor vás upozorní, že se vzor null nezpracuje. Stejné pravidlo platí, zda uzavřený typ je třída nebo struktura zvednuta na typ s možnou hodnotou null.
Další informace o tom, jak kompilátor určuje úplnost, včetně způsobu interakce uzavřených hierarchií s obecnými omezeními a přístupností, naleznete v tématu Uzavřené vzory hierarchie.
Parametry typu omezené na uzavřený typ
Parametr typu omezený na uzavřenou třídu je považován za uzavřenou třídu pro kontroly úplnosti. Výraz switch , jehož řídicí hodnota má takový parametr typu, je vyčerpávající, když zpracovává všechny přímé potomky uzavřeného omezení:
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.
};
Toto pravidlo se vztahuje na to, zda se parametr typu zobrazí v metodě nebo v obsahujícím typu.
specifikace jazyka C#
Další informace najdete ve specifikaci funkcí uzavřených hierarchií .