If you're trying to use the new C# 9 init setters on a framework earlier than .NET 5.0, you may have encountered the following error:
Error CS0518: Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported
The reason you're seeing this error is because init setters are a C# 9 feature that are only officially supported when targeting .NET 5.0 (or higher). The compiler requires that the IsExternalInit type is defined in order for the feature to work. IsExternalInit is defined in .NET 5.0, so everything works out of the box there. IsExternalInit is not defined in any of the earlier frameworks, so init setters can't be used without a workaround. Luckily, the workaround is very easy.
To "fix" this error, all you have to do is define IsExternalInit in your code. It's a simple marker class, so something like this will suffice:
using System.ComponentModel;
namespace System.Runtime.CompilerServices
{
[EditorBrowsable(EditorBrowsableState.Never)]
internal static class IsExternalInit { }
}
However, if you're multi-targeting .NET 5.0 in your project, your .NET 5.0 build will end up with an unnecessary duplicate of the IsExternalInit class.
There are a couple of options to work around that. You can remove this file from your compile target when targeting .NET 5.0, as per Daniel Cazzulino's suggestion:
<ItemGroup>
<Compile Remove="IsExternalInit.cs" Condition="'$(TargetFramework)' == 'net5.0'" />
</ItemGroup>
Or, you can use preprocessor directives to ensure that your custom IsExternalInit definition is only included when necessary, as per Brant Burnett's suggestion:
#if NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NETCOREAPP3_0 || NETCOREAPP3_1 || NET45 || NET451 || NET452 || NET6 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48
using System.ComponentModel;
namespace System.Runtime.CompilerServices
{
[EditorBrowsable(EditorBrowsableState.Never)]
internal static class IsExternalInit { }
}
#endif
Either of these approaches are fine. It's up to personal taste.
There's a very enlightening discussion on GitHub that covers this situation in more detail, but the approaches above should be sufficient to help you resolve this issue.
I hope you found this blog post helpful.