问题描述
我有一个使用 .NET Standard 2.1 和 .NET core 3.1 的项目 - 所以 C# 版本是 8.0
根据我发现的几篇文章(例如 one、two),应该可以使用以下语法定义 record
类型:
public class MyRecord(string Input1,int Input2);
但是我得到了很多编译错误,因为这种定义类的语法显然是不正确的。
这些文章是否具有误导性?
是使用记录升级到 C# 9.0,进而升级到 .NET 5.0 的唯一方法吗?
解决方法
我有一个使用 .NET Standard 2.1 和 .NET core 3.1 的项目 - 所以 C# 版本是 8.0
不正确。 默认 C# 版本是 8.0,但您可以使用任何您喜欢的语言版本(只要您拥有正确的构建工具和构建 SDK),只需更改语言版本。最简单的方法是在 csproj 中:
<PropertyGroup>
<LangVersion>9.0</LangVersion>
</PropertyGroup>
有一些注意事项:
- 某些功能需要额外的类型定义,这些在早期框架中是缺失的,但可以手动添加或通过额外的 nuget 包引用添加;在记录的情况下,这可能需要
IsExternalInit
,PMF 向您展示了如何定义,here - 某些功能需要运行时功能,并且无法在早期框架上运行,例如新的默认接口实现功能
- you won't get any support from Microsoft - 如果有效,那就太好了;如果没有;嗯
是使用记录升级到 C# 9.0,进而升级到 .NET 5.0 的唯一方法吗?
没有;您需要 .NET 5 构建 SDK,但您仍然可以面向 .NET Core 3.1 等。
,为避免错误 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 下工作。
感谢其他 2 个答案,我现在明白了我遇到的问题
我的 csproj 包含这一行
<LangVersion>latest</LangVersion>
所以我使用的是 C# 9.0,实际上我可以像这样使用 record
关键字
public record MyRecord
{
public string Input1 { get; set; }
public int Input2 { get; set; }
}
但如果我想使用我的问题中更简洁的语法,我需要在 PMF 的答案中包含 IsExternalInit
事实上这会让我把它定义为
public sealed record MyRecord(string Input1,int Input2);
另外值得注意的是 Jon Skeet 的评论,这可能最终会发布到 8.X 的某个版本