What's new in C# 14
C# 14 includes the following new features. You can try these features using the latest Visual Studio 2022 version or the .NET 10 SDK:
nameof
supports unbound generic types- More implicit conversions for
Span<T>
andReadOnlySpan<T>
- Modifiers on simple lambda parameters
field
backed properties
C# 14 is supported on .NET 10. For more information, see C# language versioning.
You can download the latest .NET 10 SDK from the .NET downloads page. You can also download Visual Studio 2022, which includes the .NET 10 SDK.
New features are added to the "What's new in C#" page when they're available in public preview releases. The working set section of the roslyn feature status page tracks when upcoming features are merged into the main branch. This article was last updated for .NET 10 Preview 1.
You can find any breaking changes introduced in C# 14 in our article on breaking changes.
Note
We're interested in your feedback on these features. If you find issues with any of these new features, create a new issue in the dotnet/roslyn repository.
The field
keyword
The token field
enables you to write a property accessor body without declaring an explicit backing field. The token field
is replaced with a compiler synthesized backing field.
For example, previously, if you wanted to ensure that a string
property couldn't be set to null
, you had to declare a backing field and implement both accessors:
private string _msg;
public string Message
{
get => _msg;
set => _msg = value ?? throw new NullArgumentException(nameof(value));
}
You can now simplify your code to:
public string Message
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
You can declare a body for one or both accessors for a field backed property.
There's a potential breaking change or confusion reading code in types that also include a symbol named field
. You can use @field
or this.field
to disambiguate between the field
keyword and the identifier, or you can rename the current field
symbol to provide more distinction.
If you try this feature and have feedback, comment on the feature issue in the csharplang
repository.
The field
contextual keyword is in C# 13 as a preview feature. You can try it if you're using .NET 9 and C# 13 to provide feedback.
Implicit span conversions
C# 14 introduces first-class support for System.Span<T> and System.ReadOnlySpan<T> in the language. This support involves new implicit conversions allowing more natural programming with these types.
Span<T>
and ReadOnlySpan<T>
are used in many key ways in C# and the runtime. Their introduction improves performance without risking safety. C# 14 recognizes the relationship and supports some conversions between ReadOnlySpan<T>
, Span<T>
, and T[]
. The span types can be extension method receivers, compose with other conversions, and help with generic type inference scenarios.
You can find the list of implicit span conversions in the article on built-in types in the language reference section. You can learn more details by reading the feature specification for First class span types.
Unbound generic types and nameof
Beginning with C# 14, the argument to nameof
can be an unbound generic type. For example, nameof(List<>)
evaluates to List
. In earlier versions of C#, only closed generic types, such as List<int>
, could be used to return the List
name.
Simple lambda parameters with modifiers
Beginning with C# 14, you can add parameter modifiers, such as scoped
, ref
, in
, out
, or ref readonly
to lambda expression parameters without specifying the parameter type:
delegate bool TryParse<T>(string text, out T result);
// ...
TryParse<int> parse1 = (text, out result) => Int32.TryParse(text, out result);
Previously, adding any modifiers was allowed only when the parameter declarations included the types for the parameters. The preceding declaration would require typs on all parameters:
TryParse<int> parse2 = (string text, out int result) => Int32.TryParse(text, out result);
The params
modifier still requires an explicitly typed parameter list.
You can read more about these changes in the article on lambda expressions in the C# language reference.