NDepend Blog

Improve your .NET code quality with NDepend

Using C#9 record and init property in your .NET Framework 4.x, .NET Standard and .NET Core projects

November 25, 2020 2 minutes read

C#9 record and C#9 init property are really nice addition to the language. As explained in C#9 records: immutable classes, both are syntactic sugar that don’t require any change at IL level nor runtime levels. It is then legit to want to use them in your projects targeting:

  • .NET Framework version 4.0 or upper
  • .NET Core version 2.0 or upper
  • .NET Standard version 2.0 or upper

However you cannot use these syntaxes as-is. By default C#9 is not supported on a .NET Fx 4.x projects:

C#9 not supported by default on .NET Framework projects
C#9 not supported by default on .NET Framework projects

To use record and init in your not yet migrated to .NET 5.0 projects two steps are required.

Step 1: Set LangVersion to 9.0 in your .csproj

Manually set <LangVersion>9.0</LangVersion> in your .csproj. To do so, in Visual Studio, first unload the project and second edit it. For .NET Core and .NET Standard projects you can just edit the project. There is no need to unload it first.

Set C# LangVersion 9 in your .csproj
Set C# LangVersion 9 in your .csproj

However we are not yet there. The compiler tells us to define the class System.Runtime.CompilerServices.IsExternalInit:

CS0518Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported
CS0518 Predefined type ‘System.Runtime.CompilerServices.IsExternalInit’ is not defined or imported

Step 2: Define the class IsExternalInit

.NET 5.0 added the new IsExternalInit static class in System.Runtime.dll.

You just need to define the class System.Runtime.CompilerServices.IsExternalInit anywhere in your project this way:

Et voilà!!

C#9 record and init used in a .NET Framework 4.6 project
C#9 record and init used in a .NET Framework 4.6 project

See below that it works as well for .NET Core project despite the code editor showing red squiggles: it is still unsure about this trick but it works.

C#9 record and init used in a .NET Core project
C#9 record and init used in a .NET Core project