safe(C# 參考)

safe情境關鍵字證明宣告在更新後的記憶體安全模型要求你明確做出安全選擇的地方是合理的。 你可以在編譯器無法自行extern分類的宣告上,safe例如具有明確或擴展版面配置的成員或欄位。 safe修飾語是 的對應詞unsafesafe證明呼叫者不需要unsafe上下文,同時unsafe傳遞對呼叫者進行安全審核的義務。

Important

關鍵字safe是更新後記憶體安全模型的一部分,該模型是 C# 15 與 .NET 11 中的預覽功能。 設定 LangVersion 為 以 preview 啟用語法。 為了強制執行更新後的規則,包括明確 safe 的選擇或 unsafe 要求不安全的來電者義務,請啟用 updated-memory-safety-rules 編譯器功能。 關於啟用細節,請參見 啟用更新的記憶體安全規則。 完整設計請參見 記憶體安全功能規範

外部成員

成員 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]的類型中,編譯器無法單獨分類每個實例欄位的安全性。 你要標記每個這樣的欄位,或unsafesafe

// 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# 語法和使用方式的最終來源。

關於更新後記憶體安全模型的設計,請參閱 記憶體安全功能規範

另請參閱