safe (C# リファレンス)

safeコンテキスト キーワードは、更新されたメモリ安全モデルの使用サイトでunsafe コンテキストを必要としない宣言としてマークします。 safe修飾子は、unsafeに対応する修飾子です。 safe宣言の呼び出し元には安全でないコンテキストは必要ありませんが、unsafeは安全を監査する義務を呼び出し元に伝達します。

safe キーワード自体を使用するには、呼び出し元がunsafeコンテキストを必要としない場合でも、AllowUnsafeBlocks コンパイラ オプション (-unsafe) が必要です。 通常の宣言は既定で安全であるため、安全でないコンパイルを不必要に必要としないようにするために必要な safe は省略します。

Important

safe キーワードは、更新されたメモリ 安全モデルの一部であり、C# 15 および .NET 11 のプレビュー機能です。 LangVersionをpreviewに設定して構文を有効にします。 また、明示的な safe や unsafe の選択、および安全でない呼び出し元の義務を含む更新された規則を適用するには、 updated-memory-safety-rules コンパイラ機能を有効にします。 アクティブ化の詳細については、「 更新されたメモリセーフルールを有効にする」を参照してください。 完全な設計については、 メモリ安全機能の仕様を参照してください。

許可された宣言と必須の宣言

メソッド、コンストラクター、プロパティ、フィールドなど、必須セーフでない修飾子を許可する宣言に safe を適用できます。 通常の宣言の場合、修飾子は、ソース生成コードを含め、意図したコントラクトを明示的にすることができます。 externメンバーとレイアウト フィールドに限定されるわけではありません。

特定の宣言では、更新された規則が有効になっている場合に、 safe または unsafe を明示的に選択する必要があります。 以降のセクションでは、 extern メンバーと明示的または拡張レイアウト フィールドについて説明します。

unsafeとは異なり、safeは字句コンテキストを確立しません。 メンバー本体で安全でない操作を行ったり、囲まれている安全でないコンテキストを取り消したりすることはありません。 同じ宣言で safe 修飾子と unsafe 修飾子を組み合わせることはできません。これを行うと CS9388 が生成されます。

Extern メンバー

extern メンバーはネイティブ コードを呼び出すので、コンパイラはその安全性を分類できません。 更新されたモデルでは、externまたはLibraryImportのいずれかの部分メソッドsafe含め、すべてのunsafe宣言をマークします。

// 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 はパラメーターを受け取らず、プリミティブを返すので、作成者は呼び出しが安全であることを証明し、呼び出し元は unsafe コンテキストなしでそれを使用します。 strlen はネイティブ コードが逆参照する生ポインターを受け取るので、宣言は unsafe され、その呼び出し元に義務が伝達されます。 更新されたルールを有効にすると、両方の修飾子を省略するとエラーになります。

明示的または拡張レイアウト フィールド

[StructLayout(LayoutKind.Explicit)]または[ExtendedLayout]を持つ型では、コンパイラはすべてのインスタンス フィールドの安全性を単独で分類することはできません。 このようなフィールドはすべて、 safe または 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;
}

ネイティブ ポインターを保持するフィールド、または型システムが表現できない不変の型を持つフィールドは、 unsafe。 型システムによって完全に記述された型を持つフィールドが safe。 明示的レイアウト フィールドと拡張レイアウト フィールドにも同じ規則が適用されます。 externメンバーと同様に、更新されたルールが有効になっている場合、両方の修飾子を省略するとエラーになります。

C# 言語仕様

詳細については、「C# 言語仕様の安全でないコード」を参照してください。 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。

更新されたメモリ安全モデルの設計については、 メモリ安全機能の仕様を参照してください。

こちらも参照ください