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:
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.
However we are not yet there. The compiler tells us to define the class System.Runtime.CompilerServices.IsExternalInit
:
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
namespace ClassLibrary { public record Class(string Str) { internal int Int { get; init; } } } namespace System.Runtime.CompilerServices { using System.ComponentModel; /// <summary> /// Reserved to be used by the compiler for tracking metadata. /// This class should not be used by developers in source code. /// </summary> [EditorBrowsable(EditorBrowsableState.Never)] internal static class IsExternalInit { } } |
Et voilà!!
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.