Closed moh-hassan closed 4 years ago
Ahhh, I just posted a similar question here:
(I am using preview6 sdk though)
I've encountered the same problem, and even the latest master branch (June 27) in Sharplab.io generates the same error. I've used the same fix.
Thanks for reporting the issue. This is not a bug in the compiler. The IsExternalInit
type is a new type added to .NET in the net5
time frame which is necessary to properly emit record
types and init
properties. That type was added but did not make it into the .NET 5 SDK you used. Once you upgrade to a version which has the type, believe Preview 7, this will go away.
(SDK Preview 8 + VS Pro 16.8 Preview 2.0)
This works fine now for net5.0
target framework, but if trying to target any of the net461
, net472
, net48
, netcoreapp2.1
, netcoreapp3.1
, netstandard2.0
, netstandard2.1
error will still be thrown.
If dummy class is added, the other tfms works fine.
Trivial workaround: just declare the missing type in your project:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.ComponentModel;
namespace System.Runtime.CompilerServices
{
/// <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)]
public static class IsExternalInit
{
}
}
If you're multitargeting net5.0 and other TFMs, just add this bit of MSBuild to remove it for net5.0 since it's built-in:
<ItemGroup>
<Compile Remove="IsExternalInit.cs" Condition="'$(TargetFramework)' == 'net5.0'" />
</ItemGroup>
I stil have this within net standard 2.1 projects with the release from today. an anyone confirm?
@BoasE I can confirm that. Edit: As I can see it's not a bug https://developercommunity.visualstudio.com/content/problem/1244809/error-cs0518-predefined-type-systemruntimecompiler.html
More about target framework https://docs.microsoft.com/en-us/dotnet/standard/net-standard#when-to-target-net50-vs-netstandard
I recommend adding this file to your project, based on the example above from @kzu. It will handle multi-targeting and marks the attribute as internal to avoid conflicts with other packages.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NETCOREAPP3_0 || NETCOREAPP3_1 || NET45 || NET451 || NET452 || NET46 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48
using System.ComponentModel;
// ReSharper disable once CheckNamespace
namespace System.Runtime.CompilerServices
{
/// <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
{
}
}
#endif
Thanks for the workaround. Still feels like a hack though.
I doubt that it should be the responsibility of the developer to provide internal system classes to make the compiler work properly...
Thanks for the workaround. Still feels like a hack though.
I doubt that it should be the responsibility of the developer to provide internal system classes to make the compiler work properly...
I generally agree, but this isn't the first feature like this. A similar (and larger) workaround file is necessary for nullable reference types on older frameworks. I know some language features aren't really usable on older versions of the framework, but this one is. Feels like Microsoft could publish a NuGet package that gives us what we need for older frameworks, much like was done with IAsyncEnumerable in Microsoft.Bcl.AsyncInterfaces. It could probably even be a source code package instead of a binary package. I see a couple of packages from 3rd parties that may do this, but I'd prefer something official and maintained.
I doubt that it should be the responsibility of the developer to provide internal system classes to make the compiler work properly...
This is a C# 9 feature and hence only officially supported when targeting net5.0
or higher. The IsExternalInit
type is defined there and hence requires no extra work by developers. When targeting other TFs the developer is required to provide the type.
This is how C# has functioned for many features over the years. Extension methods are a very analogous example here. Unless you target a target framework with the suporting ExtensionAttribute
type you must define it yourself.
What I added to my approach is bit of msbuild:
<ItemGroup>
<Compile Remove="IsExternalInit.cs" Condition="'$(TargetFramework)' == 'net5.0'" />
</ItemGroup>
@jaredpar
This class should not be used by developers in source code.
But we have to use the class with Microsoft.Net.Compilers.Toolset
in netcore 3.1 to support c# 9.
I checked the version 3.8.0-5.final and also it is not available.
I think the above phrase should be removed from the source and it's better if the missed class is added to Microsoft.Net.Compilers.Toolset
.
@brantburnett
That stray NET6
in your preprocessor directive is going to surprise all of the people who blindly copy + paste code from the Internet.
@brantburnett
That stray
NET6
in your preprocessor directive is going to surprise all of the people who blindly copy + paste code from the Internet.
@tullo-x86 Thanks for pointing that out, fixed.
@brantburnett Wouldn't it be enough to just do #if !NET
since NET
is defined in .NET 5 or later?
@Jorenkv Yes, that would also work. Personally, I like this more declarative approach a bit better, it makes it a bit more clear where it's used. But that's just a preference.
Version Used: Dev nuget package: Microsoft.Net.Compilers.Toolset v 3.8.0-1.20325.3
Steps to Reproduce: 1- Install Net5 Preview 5 SDK. 2- Create a console project and add the next class to use c# 9
init
feature3- Add a reference to
Microsoft.Net.Compilers.Toolset
to the project. .NET Core SDK Net5 Preview 5 is not supportinginit
of C# 9 feature yet.4- build
Expected Behavior: Build success.
Actual Behavior: The compiler raise error
5- Add this dummy class to the project:
6- build again Build success and application run sucessfully.
Is
IsExternalInit
a missing class? IfIsExternalInit
class has no role remove any calling to it.