C# 10 Features
The article Introducing C# 10 by Ken Bonny discloses some incremental but very welcome changes to the C# language in the iteration that will be released with .NET 6 in November.
In no particular order:
fieldin property accesses to manipulate the backing property without having to define it. This is a welcome improvement that will clean up useless boilerplate for properties that need to do something with the value before storing it (e.g.
requiredkeyword for properties in any of the supported types (e.g.
struct records). This lets types enforce initialization without forcing a constructor parameter. The compiler will force callers to initialize the property in the object initializer instead.
record structfor records that are value instead of reference types
withoperator will work with anonymous classes as well as declared types.
global usingsfor commonly used namespaces (e.g.
System) to cut down on clutter in files
namespacewithout braces will put all types in that file into that namespace. This cuts down on an indenting level in all files.
- Improvements to lambdas: attributes on parameters and return types, explicit return types
- Static methods on
interfaces(to round out the default-implementation feature introduced in C# 9)
- Constant interpolated
- Update from A Closer Look at 5 New Features in C# 10 by Matthew MacDonald (Medium): Introduce
!!suffix for method arguments that instructs the compiler to generated a null-check for that argument. So,
stringis not nullable, but not checked (i.e.g the developer is responsible for including a check to avoid a
NullReferenceExceptionif one slips past the compiler),
string?is nullable, and
string!!is not nullable and checked. This will avoid a ton of boilerplate argument-checks. Can’t wait.
I really appreciate how the changes build on changes that came in previous versions. There’s a very noticeable direction that they’re pulling in with these languages changes:
- Being able to write performant code (records, refs, etc.)
- Cutting down on boilerplate for common use cases (records, field, pattern-matching. etc.)
- Being able to write maintainable, backwards-compatible code (interface default methods, etc.)
- Improving type system (covariant returns, etc.)
- Turning runtime issues into compile-time issues (nullability, etc.)