C# 11 Breaking Changes : Simple Changes

C# 11 Breaking Changes : Simple Changes

I will introduce some simple changes in C# 11

Types cannot be named required

Introduced in Visual Studio 2022 version 17.3. Starting in C# 11, types cannot be named required. The compiler will report an error on all such type names. To work around this, the type name and all usages must be escaped with an @:

class required {} // Error CS9029
class @required {} // No error

This was done as required is now a member modifier for properties and fields.

Types cannot be named scoped

Introduced in Visual Studio 2022 version 17.4. Starting in C# 11, types cannot be named scoped. The compiler will report an error on all such type names. To work around this, the type name and all usages must be escaped with an @:

class scoped {} // Error CS9056
class @scoped {} // No error
ref scoped local; // Error
ref scoped.nested local; // Error
ref @scoped local2; // No error

This was done as scoped is now a modifier for variable declarations and reserved following ref in a ref type

Types cannot be named file

Introduced in Visual Studio 2022 version 17.4. Starting in C# 11, types cannot be named file. The compiler will report an error on all such type names. To work around this, the type name and all usages must be escaped with an @:

class file {} // Error CS9056
class @file {} // No error

This was done as file is now a modifier for type declarations.

Cannot return an out parameter by reference

Introduced in .NET SDK 7.0.100, Visual Studio 2022 version 17.3.

With language version C# 11 or later, or with .NET 7.0 or later, an out parameter cannot be returned by reference.

static ref T ReturnOutParamByRef(out T t)
{
t = default;
return ref t; // error CS8166: Cannot return a parameter by reference 't' because it is not a ref parameter
}

Possible workarounds are:

  1. Use System.Diagnostics.CodeAnalysis.UnscopedRefAttribute to mark the reference as unscoped. static ref T ReturnOutParamByRef([UnscopedRef] out T t) { t = default; return ref t; // ok }
  2. Change the method signature to pass the parameter by ref.
  3. static ref T ReturnRefParamByRef(ref T t) { t = default; return ref t; // ok }