我们可以在 C# 8.0 中使用 Records 吗?

Can we use Records in C# 8.0?

我有一个项目使用 .NET Standard 2.1 和 .NET core 3.1 - 所以 C# 版本是 8.0

根据我找到的几篇文章(例如 one, two),应该可以使用以下语法定义 record 类型:

public class MyRecord(string Input1, int Input2);

但是我遇到了很多编译错误,因为这种定义 class 的语法显然不正确。

这些文章是否具有误导性?

是使用记录升级到 C# 9.0 并因此升级到 .NET 5.0 的唯一方法吗?

为避免错误 Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported,只需在项目的任意位置添加以下代码:

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.
    /// This dummy class is required to compile records when targeting .NET Standard
    /// </summary>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public static class IsExternalInit
    {
    }
}

那么记录类型应该是 netstandard2.0 兼容的,这意味着它们也可以在 .NET 4.8 下工作。

I have a project using .NET Standard 2.1 and .NET core 3.1 - so the C# version is 8.0

不正确。 默认 C# 版本为 8.0,但您可以使用任何您喜欢的语言版本(只要您拥有正确的构建工具和构建 SDK) ,只需更改语言版本即可。最简单的方法是在 csproj:

<PropertyGroup>
    <LangVersion>9.0</LangVersion>
</PropertyGroup>

有一些注意事项:

  1. 一些功能需要额外的类型定义,这在早期的框架中是缺失的,但可以手动添加或通过额外的 nuget 包引用添加;在记录的情况下,这可能需要 IsExternalInit,PMF 向您展示如何定义
  2. 一些功能需要运行时功能,不能在早期框架上工作,例如新的默认接口实现功能
  3. won't get any support from Microsoft - 如果有效,那就太好了;如果没有;嗯

Is the only way to use records to upgrade to C# 9.0, and therefore .NET 5.0?

否;您需要 .NET 5 构建 SDK,但您仍然可以针对 .NET Core 3.1 等

感谢其他 2 个答案,我现在明白了我遇到的问题

我的 csproj 包含这一行

<LangVersion>latest</LangVersion>

所以我使用的是 C# 9.0,事实上我可以像这样使用 record 关键字

public record MyRecord
{
    public string Input1 { get; set; }
    public int Input2 { get; set; }
}

但是如果我想使用问题中更简洁的语法,我需要包含

中的 IsExternalInit

事实上,我可以将其定义为

public sealed record MyRecord(string Input1, int Input2);

另外值得注意的是 Jon Skeet 的评论,这可能最终会发布到 8.X

的某些版本