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

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

My dad being an early programmer in the 70's, I have been fortunate to switch from playing with Lego, to program my own micro-games, when I was still a kid. Since then I never stop programming.

I graduated in Mathematics and Software engineering. After a decade of C++ programming and consultancy, I got interested in the brand new .NET platform in 2002. I had the chance to write the best-seller book (in French) on .NET and C#, published by O'Reilly and also did manage some academic and professional courses on the platform and C#.

Over my consulting years I built an expertise about the architecture, the evolution and the maintenance challenges of large & complex real-world applications. It seemed like the spaghetti & entangled monolithic legacy concerned every sufficiently large team. As a consequence, I got interested in static code analysis and started the project NDepend in 2004.

Nowadays NDepend is a full-fledged Independent Software Vendor (ISV). With more than 12.000 client companies, including many of the Fortune 500 ones, NDepend offers deeper insight and full control on their application to a wide range of professional users around the world.

I live with my wife and our twin kids Léna and Paul in the beautiful island of Mauritius in the Indian Ocean.