System.Runtime.CompilerServices.IsExternalInit not recognized in .NET 5 project
SetTrend opened this issue ยท 13 comments
I just created a fresh WPF class library project utilizing .NET 5, still the known CS0518 Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported
error occurs.
Version Used:
3.8.0-5.20604.10 (9ed4b77)
Steps to Reproduce:
- Create a fresh WPF class library project, utilizing .NET 5
- Add some C#9 code, like
public ICommand AddCmd { get; init; }
Here's the .csproj
file's content:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DataRepository\DataRepository.csproj" />
</ItemGroup>
</Project>
Expected Behavior:
This code should compile flawlessly.
Actual Behavior:
It's required to manually add a dummy class to the project:
namespace System.Runtime.CompilerServices
{
public class IsExternalInit { }
}
I can't reproduce this behavior. I created a directory with the following two files:
wpf.cs
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
example.cs
record Point(int X, int Y);
In that directory I run dotnet build
it succeeds. This will exercise the IsExternalInit
code path because records generate it for it's positional properties. To double check though I opened up the binary in ILSpy and verified that it has the expected reference:
This seems like it's an issue specific to your setup in some way: either something with the machine or with the build environment. Possibly for example you have a Directory.Build.props
/ Directory.Build.targets
that is changing the inputs here somehow.
Probably the easiest way to dig a bit here is use the /bl
option which will produce a binary build log. Looking through that we can likely see quickly if the references that are passed in the stock projects are being passed here.
@SetTrend Frpm tge screenshot, it appears the error is occuring in a class lib not the wpf project.
Can you double check the target framework for the class lib project?
Absolutely. It's a class library generated by a Visual Studio 2019 project template. The project template is called "WPF Class Library". The project file's content I gave above.
@SetTrend The default .NET WPF class library template (called "WPF library (.NET)") is creating .NET Core 3.1 app. When I change it to .NET 5.0, I get no errors. Can you share a reproducible project in which you get the error and/or a binary log using dotnet build /bl
? That should help investigating the issue.
@Youssef1313: Sure, I'll gladly do that. At this time, my project doesn't compile as I just added two new view-models. I guess I can upload my repository on Monday. Please bear with me.
I remember now, that for this particular project in the solution I manually upgraded from a standard .NET 5 class library to WPF .NET 5 class library:
Perhaps the description therein wasn't sufficient?
I finished my sample project now and uploaded it to Github. Please find the corresponding repository here.
@SetTrend Thanks for the repro. As far as I can tell, the issue is related to referencing the .NET Standard project which defines IsExternalInit
in itself.
I think there is conflict between choosing the one defined in the .NET 5.0 runtime and the other one defined in your .NET Standard project. There is a room to make the diagnostic more clear here.
To fix the issue, either make IsExternalInit
internal class instead of public class in your .NET Standard project; or compile it conditionally based on the target framework. I'll let @jaredpar or any Microsoft employee guide you about what's the more appropriate solution.
Here is the minimal repro:
https://github.com/Youssef1313/IsExternalInitRepro
I'd suggesting debugging around:
roslyn/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs
Lines 145 to 147 in 1cca63b
and see if any conflicts are discovered, then add a new error similar to:
roslyn/src/Compilers/CSharp/Portable/CSharpResources.resx
Lines 1568 to 1570 in 68279b0
Thank you so much, @Youssef1313, for taking your valuable time and providing me with your expertise!
Your last message wasn't addressed to me, was it?
I think there is conflict between choosing the one defined in the .NET 5.0 runtime and the other one defined in your .NET Standard project. There is a room to make the diagnostic more clear here.
Agree. This seems to be the issue.
After some discussion we are going to modify the lookup rules for IsExternalInit
when creating a new init
accessor to be the following (logically):
- Prefer
IsExternalInit
from source - Prefer
IsExternalInit
from corelib - General lookup in all referenced assemblies and succeed if one instance is found
- Error when zero or more than one found