C# 編譯器對語言特性規則的選項

下列選項可控制編譯器如何解譯語言功能。 新的 MSBuild 語法會以「粗體」顯示。 較舊的 csc.exe 語法會以code style顯示。

  • CheckForOverflowUnderflow / -checked:產生溢位檢查。
  • AllowUnsafeBlocks / -unsafe:允許 unsafe 程式碼。
  • DefineConstants / -define:定義條件編譯符號。
  • LangVersion / -langversion:指定語言版本,例如 default (最新主要版本) 或 latest (最新版本,包括次要版本)。
  • Nullable / -nullable:啟用可為 Null 的內容或可為 Null 的警告。

注意

欲了解更多關於為您的專案配置這些選項的資訊,請參閱 編譯器選項

CheckForOverflowUnderflow

CheckForOverflowUnderflow 選項會控制預設溢位檢查內容,此內容會定義整數算術溢位時的程式行為。

<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>

CheckForOverflowUnderflowtrue時,預設上下文為已檢查上下文,且 overflow 檢查已啟用。 當 CheckForOverflowUnderflowfalse時,預設上下文為未勾選上下文。 此選項的預設值為 false,表示溢位檢查被禁用。

你也可以透過 checked and unchecked 語句明確控制程式碼部分的溢位檢查上下文。

關於溢位檢查上下文如何影響操作及其影響哪些操作,請參閱關於 and unchecked 陳述的文章checked

AllowUnsafeBlocks

AllowUnsafeBlocks 編譯器選項允許程式碼使用 unsafe 關鍵字來進行編譯。 這個選項的預設值為 false,表示不允許不安全的程式碼。

<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

如需 Unsafe 程式碼的詳細資訊,請參閱 Unsafe 程式碼和指標

啟用更新後的記憶體安全規則

更新後的記憶體安全規則是 C# 15 和 .NET 11 中的預覽功能。 它們使用兩種獨立的編譯器設定:

  • preview語言版本則支援新的語法與指標放寬。
  • 編譯器功能 updated-memory-safety-rules 啟用更新的規則,包括 要求-不安全的 呼叫者義務,並使編譯器以屬性在組合語言 MemorySafetyRulesAttribute 中記錄選擇。

未來有一個穩定的 SDK 屬性 MemorySafetyRules,計畫作為功能退出預覽版(例如 <MemorySafetyRules>2</MemorySafetyRules>),作為第三層啟用,但該屬性尚未實作。

專案中,請同時使用以下兩種設定:

<PropertyGroup>
  <LangVersion>preview</LangVersion>
  <Features>$(Features);updated-memory-safety-rules</Features>
</PropertyGroup>

對於檔案型程式,則加入相應的指令:

#:property Features=$(Features);updated-memory-safety-rules
#:property LangVersion=preview

AllowUnsafeBlocks 這個屬性是獨立的。 它控制來源是否可以使用該 unsafe 關鍵字。 專案可以在不允許不安全程式碼的情況下啟用更新後的規則,這時呼叫需求不安全 API 時會收到錯誤。

是否會對另一議會執行更新規則,取決於哪一方選擇加入:

  • 更新模型呼叫者,更新模型呼叫者:被呼叫者的標記會 unsafe 透過元資料傳送。 呼叫者會將每通電話給需要不安全成員的通話包圍成區 unsafe 塊。
  • 更新模型呼叫者、原始模型被callee:相容模式將任何標記中指標類型的被callee成員視為需要不安全,因此呼叫站點需要一個封閉 unsafe 區塊。 此模式避免指標式 API 無聲中失去 unsafe 其需求。
  • 原始模型呼叫者,更新模型呼叫者:原始指標規則仍然適用。 一個 Requires-unsafe 成員如果簽名中沒有指標型別,則可從安全程式碼呼叫,因為原始模型呼叫者無法讀取新的標記。

DefineConstants

DefineConstants 選項會定義程式的所有原始程式碼檔案中的符號。

<DefineConstants>name;name2</DefineConstants>

這個選項會指定您要定義的一個或多個符號名稱。 DefineConstants 選項的作用與 #define 前置處理器指示詞相同,不同之處在於編譯器選項對專案中的所有檔案都有效。 直到原始程式檔中的 #undef 指示詞移除符號的定義之前,符號在原始程式檔中都會維持已定義狀態。 使用 -define 選項時,某個檔案中的 #undef 指示詞不會對專案中的其他原始程式碼檔造成影響。 您可以使用此選項建立的符號,搭配 #if#else#elif#endif,有條件地編譯原始程式檔。 C# 編譯器本身不會定義任何您可以在原始程式碼中使用的符號或巨集;所有符號定義都必須是使用者定義。

注意

C# #define 指令不允許符號有值,就像 C++ 這類語言。 例如, #define 無法建立一個巨集或定義一個常數。 如果您需要定義常數,請使用 enum 變數。 如果你想建立 C++ 風格的巨集,可以考慮像是泛型巨集這類替代方案。 由於巨集非常可能發生錯誤,因此 C# 不允許使用巨集,而是提供較為安全的替代項目。

LangVersion

C# 編譯器的預設語言版本取決於您應用程式的目標 Framework,以及安裝的 SDK 或 Visual Studio 版本。 這些規則會以 C# 語言版本設定來定義。

警告

不要將元素設 LangVersionlatest。 此 latest 設定表示已安裝的編譯器會使用其最新版本。 這個版本會因機器而異,導致組裝不可靠。 此外,它還能啟用可能需要執行時或函式庫功能的語言功能,這些功能目前 SDK 中未包含。

LangVersion 選項會讓編譯器只接受指定 C# 語言規範中包含的語法,例如:

<LangVersion>9.0</LangVersion>

部分預覽功能除了 . 之外,還需要另外一次選擇加入 <LangVersion>preview</LangVersion>。 例如,C# 15 更新的記憶體安全規則會使用 updated-memory-safety-rules 編譯器功能。 欲了解更多資訊,請參閱 啟用更新後的記憶體安全規則

下列是有效值:

意義
preview 編譯器會接受最新預覽版本的所有有效語言語法。
latest 編譯器會接受編譯器最新已發行版本 (包括次要版本) 的語法。
latestMajor
default
編譯器會接受編譯器最新已發行主要版本的語法。
15.0 編譯器僅接受包含在 C# 15 或更低版本的語法。
14.0 編譯程式只接受 C# 14 或更低版本中包含的語法。
13.0 編譯器只接受 C# 13 或更低版本中所含的語法。
12.0 編譯器只接受 C# 12 或更低版本中所含的語法。
11.0 編譯器只接受 C# 11 或更低版本中所含的語法。
10.0 編譯器只接受 C# 10 或更低版本中所含的語法。
9.0 編譯器只接受 C# 9 或更低版本中所含的語法。
8.0 編譯器只會接受 C# 8.0 或更低版本中所含的語法。
7.3 編譯器只會接受 C# 7.3 或更低版本中所含的語法。
7.2 編譯器只會接受 C# 7.2 或更低版本中所含的語法。
7.1 編譯器只會接受 C# 7.1 或更低版本中所含的語法。
7 編譯器只會接受 C# 7.0 或更低版本中所含的語法。
6 編譯器只會接受 C# 6.0 或更低版本中所含的語法。
5 編譯器只會接受 C# 5.0 或更低版本中所含的語法。
4 編譯器只會接受 C# 4.0 或更低版本中所含的語法。
3 編譯器只會接受 C# 3.0 或更低版本中所含的語法。
ISO-2
2
編譯器只接受 ISO/IEC 23270:2006 C# (2.0) 中所含的語法。
ISO-1
1
編譯器只接受 ISO/IEC 23270:2003 C# (1.0/1.2) 中所含的語法。

考量

  • 若要確保您的專案使用目標 Framework 建議的預設編譯器版本,請勿使用 LangVersion 選項。 更新目標框架以存取更新的語言功能。

  • 使用 值指定default 與省略 LangVersion 選項不同。 指定 default 會使用編譯器支援的最新語言版本,而不考慮目標 Framework。 例如,如果未指定 LangVersion ,則從 Visual Studio 17.6 版建置以 .NET 6 為目標的專案會使用 C# 10,但如果 LangVersion 設定為 default,則會使用 C# 11。

  • LangVersion 編譯器的選項不會影響你的 C# 應用程式所參考的元資料。

  • 因為每個版本的 C# 編譯器都包含語言規格的延伸模組,所以 LangVersion 不會提供舊版編譯器的相等功能。

  • 雖然 C# 版本更新通常會與主要 .NET 版本一致,但是新語法和功能不需要繫結至該特定基礎結構版本。 每個特定功能都有其最低的 .NET API 或通用執行時需求,這些條件可能允許它在低階框架上運行,透過包含 NuGet 套件或其他函式庫。

  • 不論使用的 LangVersion 設定為何,都可以使用目前版本的通用語言執行平台來建立 .exe.dll。 其中一個例外狀況是 Friend 組件和 ModuleAssemblyName,這些都是在 -langversion:ISO-1 下運作。

如需其他方式來指定 C# 語言版本,請參閱 C# 語言版本設定

如需如何以程式設計方式設定這個編譯器選項的詳細資訊,請參閱 LanguageVersion

C# 語言規格

版本 連結 描述
C# 8.0 與更新版本 下載 PDF C# 語言規格版本 7:.NET Foundation
C# 7.3 下載 PDF 標準 ECMA-334 第 7 版
C# 6.0 下載 PDF 標準 ECMA-334 第 6 版
C# 5.0 下載 PDF 標準 ECMA-334 第 5 版
C# 3.0 下載 DOC C# 語言規格版本 3.0:Microsoft Corporation
C# 2.0 下載 PDF 標準 ECMA-334 第 4 版
C# 1.2 下載 DOC 標準 ECMA-334 第 2 版
C# 1.0 下載 DOC 標準 ECMA-334 第 1 版

支援所有語言功能所需的最低 SDK 版本

下表列出提供 C# 編譯器支援對應語言版本的 SDK 最低版本:

C# 版本 最低 SDK 版本
C# 12 Microsoft Visual Studio/Build Tools 2022 17.8 版,或 .NET 8 SDK
C# 11 Microsoft Visual Studio/Build Tools 2022 17.4 版,或 .NET 7 SDK
C# 10 Microsoft Visual Studio/Build Tools 2022,或 .NET 6 SDK
C# 9.0 Microsoft Visual Studio/Build Tools 2019 16.8 版,或 .NET 5 SDK
C# 8.0 Microsoft Visual Studio/Build Tools 2019 16.3 版,或 .NET Core 3.0 SDK
C# 7.3 Microsoft Visual Studio/Build Tools 2017 15.7 版
C# 7.2 Microsoft Visual Studio/Build Tools 2017 15.5 版
C# 7.1 Microsoft Visual Studio/Build Tools 2017 15.3 版
C# 7.0 Microsoft Visual Studio/建構工具 2017
C# 6 Microsoft Visual Studio/建構工具 2015
C# 5 Microsoft Visual Studio/Build Tools 2012 或配套的 .NET Framework 4.5 編譯器
C# 4 Microsoft Visual Studio/Build Tools 2010 或配套的 .NET Framework 4.0 編譯器
C# 3 Microsoft Visual Studio/Build Tools 2008 或配套的 .NET Framework 3.5 編譯器
C# 2 Microsoft Visual Studio/Build Tools 2005 或配套的 .NET Framework 2.0 編譯器
C# 1.0/1.2 Microsoft Visual Studio/Build Tools .NET 2002 或配套的 .NET Framework 1.0 編譯器

Nullable

使用 可空選項 來指定可空上下文。 請使用 <Nullable> 以下標籤將其設定為專案設定:

<Nullable>enable</Nullable>

引數必須是 enabledisablewarningsannotations 的其中一個。 論 enable 證的重點在於可空除的上下文。 這個 disable 論證會關閉可空的上下文。 這個 warnings 論點是建立在可撤銷警告上下文上。 該 annotations 論證基於可空標註上下文。 欲了解更多關於這些值的資訊,請參見可空上下文(Nullable contexts)。 欲了解更多如何在現有程式碼庫中啟用可空參考型別,請參閱 可空遷移策略

注意

如果你沒有設定值,預設值就是 disable。 然而,.NET 6 及更新範本預設將 Nullableenable設為 Nullable。

流程分析推斷可執行程式碼中變數的可取消性。 變數的推斷可 Null 性與變數宣告的 Null 屬性無關。 即使序列呼叫被條件性地從編譯輸出中省略,編譯器仍會分析方法呼叫。 例如,編譯器仍會分析 的 Debug.Assert 呼叫是否可空,儘管該呼叫是條件式且未編譯成版本。

引用帶有以下屬性註解的方法也會影響流程分析:

重要

全域可空的上下文不適用於產生的程式碼檔案。 不論此設定為何,所有標記為產生的來源檔案,都會「停用」內容可為 null。 檔案會以以下其中一種方式標記為已產生:

  1. 在 .editorconfig 中,於套用至該檔案的區段中,指定 generated_code = true
  2. 請在檔案頂端附<auto-generated><auto-generated/>註或註解。 你可以在註解的任意一行放置註解區塊,但註解區必須是檔案的第一個元素。
  3. 使用 TemporaryGeneratedFile_ 做為檔案名稱的開頭
  4. 使用 .designer.cs.generated.cs.g.cs.g.i.cs 做為檔案名稱的結尾。

發電機可透過預 #nullable 處理器指令選擇加入。