在 VS2019 中测试 C# 9.0 - CS0518 IsExternalInit is not defined or imported ...我如何 define/import 它?

Testing C# 9.0 in VS2019 - CS0518 IsExternalInit is not defined or imported ... How do I define/import it?

编辑 [2020 年 11 月 29 日]:.NET 5.0 现已发布,但如果您的目标是 .NET Standard 2.1

,则仍然需要以下解决方案

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

  1. Mr​​. 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。我为项目选择了 Preview 语言版本。

一些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; }
}

record Test(int hello);

记录定义为 shorthand 并扩展为使用 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>

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

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

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

using System.ComponentModel;

namespace System.Runtime.CompilerServices
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    internal class IsExternalInit{}
}

记录和 init 将正常工作。

只有 LinqPad 6 似乎没有问题,可能是因为它也包含该类型

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

using System.ComponentModel;

namespace System.Runtime.CompilerServices
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    public record IsExternalInit;
}

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

<?xml version="1.0" encoding="utf-8"?>
<Project>
    <ItemGroup>
        <Compile Include="$(MSBuildThisFileDirectory)IsExternalInit.cs" Visible="false" />
    </ItemGroup>
</Project>

Add/edit 这个文件在你的解决方案的根目录中,并在那里添加 IsExternalInit.cs 文件。这样做会将该文件自动添加到您的所有项目中。

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

.
├── Directory.Build.props
├── IsExternalInit.cs
└── Solution.sln

@Brouke 的回答很好,我会解释更多:

1 - 在您的根文件夹(解决方案文件夹)中,创建一个名为 Directory.Build.props 的文件,其中 *.pros 是其扩展名。

2 - 编辑此文件并添加:

<?xml version="1.0" encoding="utf-8"?>
<Project>
    <ItemGroup>
        <Compile Include="$(MSBuildThisFileDirectory)IsExternalInit.cs" Visible="false" />
    </ItemGroup>
</Project>

3 - 在旁边添加 IsExternalInit.cs 文件,其中:

using System.ComponentModel;

namespace System.Runtime.CompilerServices
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    public record IsExternalInit;
}

4 - 删除所有其他 IsExternalInit.cs 文件,重建解决方案并重新启动 VS。