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.