在 VS2019 中测试 C# 9.0 - CS0518 IsExternalInit 未定义或导入......我如何定义/导入它?

Jos*_*osh 50 c# c#-9.0

编辑 [2020 年 11 月 29 日]:.NET 5.0 现已发布,但如果您的目标是 .NET Standard 2.1,则仍然需要以下解决方案


C# 9.0 仍在开发中。有几个参考资料让我相信它现在应该是可测试的(无论如何,其中一些)。

  1. 由 Awesome 先生本人撰写的 Microsoft 博客,介绍了这些功能。https://devblogs.microsoft.com/dotnet/welcome-to-c-9-0/
  2. github上的语言跟踪页面:https : //github.com/dotnet/roslyn/blob/master/docs/Language%20Feature%20Status.md

我正在使用 VS 2019 16.7 预览版 3.1。我选择了语言版本作为项目的预览

一些 C# 9 功能,我可以使用。喜欢:Dictionary<string, object> Stuff = new()

但是使用新init功能会给我这个错误:Error CS0518 Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported

我该如何解决?

导致错误的代码示例:

class Test
{
   public int Hello { get; init; }
}
Run Code Online (Sandbox Code Playgroud)

record Test(int hello);
Run Code Online (Sandbox Code Playgroud)

记录定义是速记并扩展为使用 的内容init,这就是它也受到影响的原因。

我上面链接的语言跟踪页面说该功能是Merged into 16.7p3我正在使用的。

我只是太兴奋了吗?我需要等待吗?或者现在有没有办法使用这些功能:D

编辑(在评论中要求) - 为 .net 5.0 控制台应用程序添加 csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <LangVersion>preview</LangVersion>
  </PropertyGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)

编辑 #2:此处发布的解决方法 - https://github.com/dotnet/roslyn/issues/45510

Pan*_*vos 71

这是当前预览版最新主分支(6 月 27 日)中的错误。在sharplab.io 中的一个简单记录会产生相同的错误。

只需在项目中的某处添加缺少的类型

using System.ComponentModel;

namespace System.Runtime.CompilerServices
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    internal class IsExternalInit{}
}
Run Code Online (Sandbox Code Playgroud)

记录init并将正常工作。

只有 LinqPad 6 似乎可以正常工作,可能是因为它也包含该类型

  • 当 TargetFramework netstandard2.0 与 LangVersion 9.0 一起使用时,我遇到了此错误。这堂课让它发挥作用。 (3认同)
  • 我有 5.0 发行版,但它仍然是一个问题 wtf (2认同)
  • @PanagiotisKanavos:我经历了和你一样的经历(在许多其他项目中只有一个 .NET 5.0 项目在记录声明上遇到了这个麻烦)。我发现这种情况发生在引用其他项目的项目上,其中 .NET Standard 2.0 与 C#9.0 功能(如“记录”功能)一起使用。如果我从参考中删除这个项目,错误就会消失。一旦我重新添加对项目的引用,它就会重新出现。如果您已经在旧项目中添加了该类,也没关系,您也必须将其添加到当前项目中。 (2认同)
  • **非常重要**:不要*在此声明周围放置`#if`。有关详细信息,请参阅 https://twitter.com/aarnott/status/1362786409954766858。另外,将其设为*内部*。 (2认同)

Bou*_*uke 21

如果您不喜欢在每个项目中乱扔类IsExternalInit,您可以使用Directory.Build.props自动引用该文件作为不可见的编译项:

\n
<?xml version="1.0" encoding="utf-8"?>\n<Project>\n    <ItemGroup>\n        <Compile Include="$(MSBuildThisFileDirectory)IsExternalInit.cs" Visible="false" />\n    </ItemGroup>\n</Project>\n
Run Code Online (Sandbox Code Playgroud)\n

在解决方案的根目录中添加/编辑此文件,并IsExternalInit.cs在其中添加该文件。这样做会自动将该文件添加到您的所有项目中。

\n

与您的解决方案相关的示例文件夹结构:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Directory.Build.props\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 IsExternalInit.cs\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 Solution.sln\n
Run Code Online (Sandbox Code Playgroud)\n


myc*_*oes 10

借用 Panagiotis Kanavos,您实际上可以将其声明IsExternalInit为记录本身(自我实现的预言):

using System.ComponentModel;

namespace System.Runtime.CompilerServices
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    public record IsExternalInit;
}
Run Code Online (Sandbox Code Playgroud)