C# Compiler Options for language feature rules

The following options control how the compiler interprets language features. The new MSBuild syntax is shown in Bold. The older csc.exe syntax is shown in code style.

  • CheckForOverflowUnderflow / -checked: Generate overflow checks.
  • AllowUnsafeBlocks / -unsafe: Allow 'unsafe' code.
  • DefineConstants / -define: Define conditional compilation symbol(s).
  • LangVersion / -langversion: Specify language version such as default (latest major version), or latest (latest version, including minor versions).
  • Nullable / -nullable: Enable nullable context, or nullable warnings.

CheckForOverflowUnderflow

The CheckForOverflowUnderflow option specifies whether an integer arithmetic statement that results in a value that is outside the range of the data type causes a run-time exception.

<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>

An integer arithmetic statement that is in the scope of a checked or unchecked keyword isn't subject to the effect of the CheckForOverflowUnderflow option. If an integer arithmetic statement that isn't in the scope of a checked or unchecked keyword results in a value outside the range of the data type, and CheckForOverflowUnderflow is true, that statement causes an exception at run time. If CheckForOverflowUnderflow is false, that statement doesn't cause an exception at run time. The default value for this option is false; overflow checking is disabled.

AllowUnsafeBlocks

The AllowUnsafeBlocks compiler option allows code that uses the unsafe keyword to compile. The default value for this option is false, meaning unsafe code is not allowed.

<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

For more information about unsafe code, see Unsafe Code and Pointers.

DefineConstants

The DefineConstants option defines symbols in all source code files of your program.

<DefineConstants>name;name2</DefineConstants>

This option specifies the names of one or more symbols that you want to define. The DefineConstants option has the same effect as the #define preprocessor directive except that the compiler option is in effect for all files in the project. A symbol remains defined in a source file until an #undef directive in the source file removes the definition. When you use the -define option, an #undef directive in one file has no effect on other source code files in the project. You can use symbols created by this option with #if, #else, #elif, and #endif to compile source files conditionally. The C# compiler itself defines no symbols or macros that you can use in your source code; all symbol definitions must be user-defined.

Note

The C# #define directive does not allow a symbol to be given a value, as in languages such as C++. For example, #define cannot be used to create a macro or to define a constant. If you need to define a constant, use an enum variable. If you want to create a C++ style macro, consider alternatives such as generics. Since macros are notoriously error-prone, C# disallows their use but provides safer alternatives.

LangVersion

Causes the compiler to accept only syntax that is included in the chosen C# language specification.

<LangVersion>9.0</LangVersion>

The following values are valid:

Value Meaning
preview The compiler accepts all valid language syntax from the latest preview version.
latest The compiler accepts syntax from the latest released version of the compiler (including minor version).
latestMajor (default) The compiler accepts syntax from the latest released major version of the compiler.
10.0 The compiler accepts only syntax that is included in C# 10.0 or lower.
9.0 The compiler accepts only syntax that is included in C# 9.0 or lower.
8.0 The compiler accepts only syntax that is included in C# 8.0 or lower.
7.3 The compiler accepts only syntax that is included in C# 7.3 or lower.
7.2 The compiler accepts only syntax that is included in C# 7.2 or lower.
7.1 The compiler accepts only syntax that is included in C# 7.1 or lower.
7 The compiler accepts only syntax that is included in C# 7.0 or lower.
6 The compiler accepts only syntax that is included in C# 6.0 or lower.
5 The compiler accepts only syntax that is included in C# 5.0 or lower.
4 The compiler accepts only syntax that is included in C# 4.0 or lower.
3 The compiler accepts only syntax that is included in C# 3.0 or lower.
ISO-2 (or 2) The compiler accepts only syntax that is included in ISO/IEC 23270:2006 C# (2.0).
ISO-1 (or 1) The compiler accepts only syntax that is included in ISO/IEC 23270:2003 C# (1.0/1.2).

The default language version depends on the target framework for your application and the version of the SDK or Visual Studio installed. Those rules are defined in C# language versioning.

Metadata referenced by your C# application isn't subject to the LangVersion compiler option.

Because each version of the C# compiler contains extensions to the language specification, LangVersion doesn't give you the equivalent functionality of an earlier version of the compiler.

Additionally, while C# version updates generally coincide with major .NET Framework releases, the new syntax and features aren't necessarily tied to that specific framework version. While the new features definitely require a new compiler update that is also released alongside the C# revision, each specific feature has its own minimum .NET API or common language runtime requirements that may allow it to run on downlevel frameworks by including NuGet packages or other libraries.

Regardless of which LangVersion setting you use, use the current version of the common language runtime to create your .exe or .dll. One exception is friend assemblies and ModuleAssemblyName, which work under -langversion:ISO-1.

For other ways to specify the C# language version, see C# language versioning.

For information about how to set this compiler option programmatically, see LanguageVersion.

C# language specification

Version Link Description
C# 7.0 and later Not currently available
C# 6.0 Link C# Language Specification Version 6 - Unofficial Draft: .NET Foundation
C# 5.0 Download PDF Standard ECMA-334 5th Edition
C# 3.0 Download DOC C# Language Specification Version 3.0: Microsoft Corporation
C# 2.0 Download PDF Standard ECMA-334 4th Edition
C# 1.2 Download DOC C# Language Specification Version 1.2: Microsoft Corporation
C# 1.0 Download DOC C# Language Specification Version 1.0: Microsoft Corporation

Minimum SDK version needed to support all language features

The following table lists the minimum versions of the SDK with the C# compiler that supports the corresponding language version:

C# version Minimum SDK version
C# 10.0 Microsoft Visual Studio/Build Tools 2022, or .NET 6.0 SDK
C# 9.0 Microsoft Visual Studio/Build Tools 2019, version 16.8, or .NET 5.0 SDK
C# 8.0 Microsoft Visual Studio/Build Tools 2019, version 16.3, or .NET Core 3.0 SDK
C# 7.3 Microsoft Visual Studio/Build Tools 2017, version 15.7
C# 7.2 Microsoft Visual Studio/Build Tools 2017, version 15.5
C# 7.1 Microsoft Visual Studio/Build Tools 2017, version 15.3
C# 7.0 Microsoft Visual Studio/Build Tools 2017
C# 6 Microsoft Visual Studio/Build Tools 2015
C# 5 Microsoft Visual Studio/Build Tools 2012 or bundled .NET Framework 4.5 compiler
C# 4 Microsoft Visual Studio/Build Tools 2010 or bundled .NET Framework 4.0 compiler
C# 3 Microsoft Visual Studio/Build Tools 2008 or bundled .NET Framework 3.5 compiler
C# 2 Microsoft Visual Studio/Build Tools 2005 or bundled .NET Framework 2.0 compiler
C# 1.0/1.2 Microsoft Visual Studio/Build Tools .NET 2002 or bundled .NET Framework 1.0 compiler

Nullable

The Nullable option lets you specify the nullable context.

<Nullable>enable</Nullable>

The argument must be one of enable, disable, warnings, or annotations. The enable argument enables the nullable context. Specifying disable will disable the nullable context. When providing the warnings argument the nullable warning context is enabled. When specifying the annotations argument, the nullable annotation context is enabled.

Flow analysis is used to infer the nullability of variables within executable code. The inferred nullability of a variable is independent of the variable's declared nullability. Method calls are analyzed even when they're conditionally omitted. For instance, Debug.Assert in release mode.

Invocation of methods annotated with the following attributes will also affect flow analysis:

Important

The global nullable context does not apply for generated code files. Regardless of this setting, the nullable context is disabled for any source file marked as generated. There are four ways a file is marked as generated:

  1. In the .editorconfig, specify generated_code = true in a section that applies to that file.
  2. Put <auto-generated> or <auto-generated/> in a comment at the top of the file. It can be on any line in that comment, but the comment block must be the first element in the file.
  3. Start the file name with TemporaryGeneratedFile_
  4. End the file name with .designer.cs, .generated.cs, .g.cs, or .g.i.cs.

Generators can opt-in using the #nullable preprocessor directive.