Skip to content

/flags/csharp/dotnet-build-langversion

C# LangVersion (dotnet build -p:LangVersion): fix "Feature is not available in C# N"

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · 10.0.401updated
tool
C#
command
dotnet build
flag
-p:LangVersion=<version> (<LangVersion> in the .csproj)
default
the C# version that matches the target framework (C# 14 for net10.0)

<LangVersion> in a .csproj, or dotnet build -p:LangVersion=11 for one build, selects which C# language version the compiler accepts. Code that uses a newer feature fails with an error that names the feature and the version it needs, for example error CS9058: Feature 'collection expressions' is not available in C# 11.0. Please use language version 12.0 or greater. Without the property, the compiler uses the default version of the project's target framework.

A modern file compiled with older versions

bash
dotnet new console -n App -o . >/dev/null 2>&1
cat > Program.cs <<'EOF'
namespace Demo;

record Point(int X, int Y);

static class Program
{
    static void Main()
    {
        int[] nums = [1, 2, 3];
        Console.WriteLine($"{nums.Length} {new Point(1, 2)}");
    }
}
EOF
build() { dotnet build --no-incremental "$@" 2>&1 | grep -oE "(warning|error) CS[0-9]+[^[]*" | sort -u; echo "exit: ${PIPESTATUS[0]}"; }
for v in default 11 9 7.3 99; do
  echo "== LangVersion=$v"
  if [ "$v" = default ]; then build; else build -p:LangVersion=$v; fi
done

Output

== LangVersion=default
exit: 0
== LangVersion=11
error CS9058: Feature 'collection expressions' is not available in C# 11.0. Please use language version 12.0 or greater.
exit: 1
== LangVersion=9
error CS8773: Feature 'file-scoped namespace' is not available in C# 9.0. Please use language version 10.0 or greater.
error CS8773: Feature 'global using directive' is not available in C# 9.0. Please use language version 10.0 or greater.
exit: 1
== LangVersion=7.3
error CS8630: Invalid 'nullable' value: 'Enable' for C# 7.3. Please use language version '8.0' or greater.
exit: 1
== LangVersion=99
error CS1617: Invalid option '99' for /langversion. Use '/langversion:?' to list supported values.
exit: 1

The default (C# 14 on net10.0) compiles everything. C# 11 rejects only the collection expression [1, 2, 3]. C# 9 already fails on the file-scoped namespace and on the global using directives that ImplicitUsings generates. C# 7.3 does not even know nullable reference types, which the template enables, so the error is about the nullable option. An unknown value fails with CS1617.

Values

ValueMeaning
(not set)Default for the target framework: C# 14 for net10.0, 13 for net9.0, 12 for net8.0
14, 13, 12, 11, 10, 9, 8, 7.3...That exact version
latestLatest released version the compiler supports, including minor versions
latestMajorLatest released major version
previewLatest preview features of the compiler
defaultSame as latestMajor in current compilers

Errors that point to LangVersion

ErrorMeaning
CS8773 / CS9058: Feature X is not available in C# NRaise LangVersion, or (better) the target framework
CS8630: Invalid nullable value for C# 7.3Nullable needs C# 8.0; remove <Nullable> or raise LangVersion
CS1617: Invalid option for /langversionThe value is misspelled or unknown to this compiler version

The error number depends on the feature (older features use other numbers, such as CS8370 for features of C# 8.0); the message text always names the feature and the minimum version.

Where to set it

App.csproj
<PropertyGroup>
  <TargetFramework>net10.0</TargetFramework>
  <!-- Usually leave LangVersion unset; pin it only when you must -->
  <LangVersion>12</LangVersion>
</PropertyGroup>

Put it in Directory.Build.props to give a whole repository the same version. Avoid latest in shared builds: a newer SDK on a developer machine then accepts code that the CI SDK rejects.

Pitfalls

  • Pinning an old LangVersion does not make the code run on an old runtime; that is the job of TargetFramework.
  • Changing only the property on the command line may not recompile in an incremental build; use --no-incremental or dotnet build -t:Rebuild when experimenting, as the example does.
  • A missing namespace or type is not a language-version problem: CS0246 means a reference or using is missing.

FAQ

Which C# version does my project use if LangVersion is not set?

The default depends on the target framework: each .NET version has a default C# version (for example C# 12 for .NET 8, C# 13 for .NET 9 and C# 14 for .NET 10). Changing TargetFramework changes the language version too.

Is it safe to set LangVersion to latest on an older target framework?

It compiles, but Microsoft does not support newer language versions on older frameworks: some features need runtime or library support (default interface members, required members, ref fields) and fail or behave unexpectedly. Prefer upgrading the target framework.

How do I list the language versions my compiler supports?

The C# compiler accepts -langversion:? to print them. With the SDK, an invalid value fails with CS1617 and points to the same switch.

Sources