safe (odwołanie w C#)

Kontekstowe safe słowo kluczowe oznacza deklarację jako nie wymagającą unsafe kontekstu w jego lokacji użycia w ramach zaktualizowanego modelu bezpieczeństwa pamięci. Modyfikator safe jest odpowiednikiem .unsafe Niebezpieczny kontekst nie jest wymagany dla osób wywołujących deklarację safe , podczas gdy unsafe propaguje obowiązek inspekcji bezpieczeństwa rozmówcy.

safe Użycie samego słowa kluczowego AllowUnsafeBlocks wymaga opcji kompilatora (-unsafe), mimo że wywołujące nie potrzebują unsafe kontekstu. Zwykłe deklaracje są domyślnie bezpieczne, więc pomijaj safe je, gdy nie jest wymagane, aby uniknąć niepotrzebnego wymagania niebezpiecznej kompilacji.

Ważna

Słowo safe kluczowe jest częścią zaktualizowanego modelu bezpieczeństwa pamięci, funkcji w wersji zapoznawczej w języku C# 15 i .NET 11. Ustaw LangVersion wartość na , aby preview włączyć składnię. Aby również wymusić zaktualizowane reguły, w tym jawne safe lub unsafe wybory i wymaga niebezpiecznych zobowiązań wywołujących, włącz funkcję kompilatora updated-memory-safety-rules . Aby uzyskać szczegółowe informacje na temat aktywacji, zobacz Włączanie zaktualizowanych reguł bezpieczeństwa pamięci. Aby uzyskać pełny projekt, zobacz specyfikację funkcji bezpieczeństwa pamięci.

Dozwolone i wymagane deklaracje

Można zastosować safe do deklaracji, które zezwalają na modyfikator wymaga niebezpiecznego, w tym metod, konstruktorów, właściwości i pól. W przypadku zwykłych deklaracji modyfikator może jawnie określić zamierzony kontrakt, w tym w kodzie generowanym przez źródło. Nie jest ograniczona do extern elementów członkowskich i pól układu.

Niektóre deklaracje wymagają wyraźnego safe wyboru lub unsafe włączenia zaktualizowanych reguł. W poniższych sekcjach opisano extern elementy członkowskie i jawne lub rozszerzone pola układu.

W przeciwieństwie do unsafeelementu nie safe ustanawia kontekstu leksyktycznego. Nie powoduje to, że niebezpieczne operacje w ciele elementu członkowskiego są bezpieczne ani nie są anulowane otaczającego niebezpiecznego kontekstu. Nie można połączyć safe modyfikatorów i unsafe w tej samej deklaracji; w ten sposób tworzy CS9388.

W nowszych kompilatorach safe deklaracje wymagają AllowUnsafeBlocksrównież , mimo że wywołujące nie potrzebują niebezpiecznego kontekstu. Ustaw <AllowUnsafeBlocks>true</AllowUnsafeBlocks> w pliku projektu, aby rozwiązać problem CS9401. Ta kontrola modyfikatora jest niezależna od zgody na wymuszanie zasad aktualizacji. Roslyn dokumentuje go zgodnie z wprowadzeniem w Visual Studio 2026 w wersji 18.13, po .NET 11.0.100; kompilator .NET 11 RC2 nie wymusza tego wymagania dla programu safe. Aby zapoznać się z granicą kompilatora i rozróżnieniem z CS0227 w niebezpiecznych blokach, zobacz Wymagania dotyczące niebezpiecznego kontekstu.

Członkowie extern

Element extern członkowski wywołuje kod natywny, więc kompilator nie może sklasyfikować jego bezpieczeństwa. W ramach zaktualizowanego modelu oznaczasz każdą extern deklarację, w tym metodę częściową LibraryImport lub 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 nie przyjmuje parametrów i zwraca element pierwotny, dlatego autor potwierdza, że wywołanie jest bezpieczne, a osoby wywołujące używają go bez unsafe kontekstu. strlen przyjmuje nieprzetworzone wskaźniki, że kod natywny wyłuska, więc deklaracja jest unsafe i propaguje obowiązek jego obiektów wywołujących. Po włączeniu zaktualizowanych reguł pomijanie obu modyfikatorów jest błędem.

Jawne lub rozszerzone pola układu

W typie z elementem [StructLayout(LayoutKind.Explicit)] lub [ExtendedLayout]kompilator nie może samodzielnie sklasyfikować bezpieczeństwa każdego pola wystąpienia. Oznaczasz każde takie pole lub safeunsafe:

// 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, które zawiera wskaźnik macierzysty lub którego typ w inny sposób niesie niezmienny system typów, nie może wyrazić, to unsafe. Pole, którego typ jest w pełni opisany przez system typów, to safe. Ta sama reguła ma zastosowanie do pól jawnego układu i pól układu rozszerzonego. Podobnie jak w przypadku extern elementów członkowskich pominięcie obu modyfikatorów jest błędem po włączeniu zaktualizowanych reguł.

Zastosuj te same modyfikatory do pól wystąpień w typach z niezerowymi StructLayoutAttribute.Pack lub StructLayoutAttribute.Size, w tym sekwencyjnym i automatycznym układem. Na przykład typ sekwencyjnego układu wymaga Pack = 1 tego samego jawnego wyboru. Nieokreślone lub zerowe wartości nie wyzwalają dodatkowej reguły samodzielnie. Pola statyczne i stałe są wykluczone. W przypadku syntetyzowanych pól kopii zapasowych należy umieścić modyfikator we właściwości lub zdarzeniu.

Aby zapoznać się z komunikatem CS9392 i poprawkami dla innego syntetyzowanego magazynu, zobacz Bezpieczeństwo układu pola.

specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz Niebezpieczny kod w specyfikacji języka C#. Specyfikacja języka jest ostatecznym źródłem informacji o składni i użyciu języka C#.

Aby zapoznać się z projektem zaktualizowanego modelu bezpieczeństwa pamięci, zobacz specyfikację funkcji bezpieczeństwa pamięci.

Informacje dodatkowe