safe (Referenční dokumentace jazyka C#)

Kontextové safe klíčové slovo označuje deklaraci, která nevyžaduje unsafe kontext v lokalitě jejího použití v aktualizovaném modelu bezpečnosti paměti. safe Modifikátor je protějškem unsafe. Pro volající deklarace safe není vyžadován nebezpečný kontext, zatímco unsafe se šíří povinnost auditovat bezpečnost volajícího.

Použití samotného klíčového safe slova vyžaduje možnost kompilátoru AllowUnsafeBlocks (-unsafe), i když volající nepotřebují unsafe kontext. Běžné deklarace jsou ve výchozím nastavení bezpečné, proto vynechejte safe , kde není nutné zbytečně vyžadovat nebezpečnou kompilaci.

Important

Klíčové safe slovo je součástí aktualizovaného modelu zabezpečení paměti, funkce Preview v jazyce C# 15 a .NET 11. Nastavte LangVersion na preview povolení syntaxe. Pokud chcete také vynutit aktualizovaná pravidla, včetně explicitních safe nebo unsafe voleb a vyžaduje nebezpečné povinnosti volajícího, povolte funkci kompilátoru updated-memory-safety-rules . Podrobnosti o aktivaci najdete v tématu Povolení aktualizovaných pravidel zabezpečení paměti. Úplný návrh najdete ve specifikaci funkce bezpečnosti paměti.

Povolené a požadované deklarace

Můžete použít safe u deklarací, které umožňují modifikátor vyžadující nebezpečné, včetně metod, konstruktorů, vlastností a polí. U běžných deklarací může modifikátor nastavit zamýšlený kontrakt explicitně, včetně zdrojového kódu generovaného. Není omezena na extern pole členů a rozložení.

Určité deklarace vyžadují explicitní volbu safe nebo unsafe když jsou povolená aktualizovaná pravidla. Následující části popisují extern členy a explicitní nebo rozšířená pole rozložení.

Na rozdíl od unsafe, safe nenavazuje lexikální kontext. Neprovádí nebezpečné operace v těle člena v bezpečí nebo ruší uzavřený nebezpečný kontext. Nemůžete kombinovat safe modifikátory ve unsafe stejné deklaraci. Výsledkem je CS9388.

V novějších kompilátorech safe vyžadují AllowUnsafeBlocksdeklarace také , i když volající nepotřebují nebezpečný kontext. Nastavte <AllowUnsafeBlocks>true</AllowUnsafeBlocks> v souboru projektu řešení CS9401. Tato kontrola modifikátoru je nezávislá na výslovném souhlasu s aktualizovanými pravidly. Roslyn dokumentuje, jak je zavedeno v Visual Studio 2026 verze 18.13, po .NET 11.0.100; kompilátor .NET 11 RC2 nevynucuje tento požadavek pro safe. Pro hranice kompilátoru a rozdíl od CS0227 na nebezpečných blocích viz požadavky na nebezpečný kontext.

Extern členové

Člen extern volá nativní kód, takže kompilátor nemůže klasifikovat jeho bezpečnost. V rámci aktualizovaného modelu označíte každou extern deklaraci, včetně LibraryImport částečné metody, nebo safeunsafe:

// Syntax requires LangVersion preview; enforcement requires the updated-memory-safety-rules compiler feature.
[LibraryImport("libc")]
internal static safe partial int getpid();

[LibraryImport("libc", StringMarshalling = StringMarshalling.Utf8)]
internal static unsafe partial nint strlen(byte* str);

getpid nepřijímá žádné parametry a vrací primitivní hodnotu, takže autor ověřuje, že volání je bezpečné a volající ho používají bez unsafe kontextu. strlen přebírá nezpracovaný ukazatel, který nativní kód dereferences, takže deklarace je unsafe a šíří povinnost svým volajícím. Když jsou povolená aktualizovaná pravidla, vynechání obou modifikátorů je chyba.

Explicitní nebo rozšířená pole rozložení

V typu s [StructLayout(LayoutKind.Explicit)] nebo [ExtendedLayout]nemůže kompilátor klasifikovat bezpečnost každého pole instance samostatně. Každé takové pole označíte buď safe takto, nebo unsafe:

// Syntax requires LangVersion preview; enforcement requires the updated-memory-safety-rules compiler feature.
[StructLayout(LayoutKind.Explicit)]
internal struct Union
{
    [FieldOffset(0)]
    internal safe int AsInt;

    [FieldOffset(0)]
    internal safe float AsFloat;
}

Pole, které obsahuje nativní ukazatel nebo jehož typ jinak nese invariantní systém typů nemůže vyjádřit, je unsafe. Pole, jehož typ je plně popsán systémem typů je safe. Stejné pravidlo platí pro pole explicitního rozložení a pole rozšířeného rozložení. Stejně jako u extern členů je vynechání obou modifikátorů chybou při povolení aktualizovaných pravidel.

Použijte stejné modifikátory u polí instancí v typech s nenulovým StructLayoutAttribute.Pack nebo StructLayoutAttribute.Size, včetně sekvenčního a automatického rozložení. Například typ sekvenčního rozložení, který Pack = 1 vyžaduje stejnou explicitní volbu. Nezadané nebo nulové hodnoty neaktivují samotné další pravidlo. Statická a konstantní pole jsou vyloučená. Pro syntetizovaná backingová pole vložte modifikátor na vlastní vlastnost nebo událost.

Informace o zprávě CS9392 a opravy pro jiné syntetizované úložiště naleznete v tématu Bezpečnost rozložení pole.

specifikace jazyka C#

Další informace naleznete v tématu Nebezpečný kód ve specifikaci jazyka C#. Specifikace jazyka je konečným zdrojem syntaxe a použití jazyka C#.

Návrh aktualizovaného modelu bezpečnosti paměti naleznete ve specifikaci funkce bezpečnosti paměti.

Viz také