我们可以在 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>
有一些注意事项:
- 一些功能需要额外的类型定义,这在早期的框架中是缺失的,但可以手动添加或通过额外的 nuget 包引用添加;在记录的情况下,这可能需要
IsExternalInit
,PMF 向您展示如何定义
- 一些功能需要运行时功能,不能在早期框架上工作,例如新的默认接口实现功能
- 你 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
的某些版本
我有一个项目使用 .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>
有一些注意事项:
- 一些功能需要额外的类型定义,这在早期的框架中是缺失的,但可以手动添加或通过额外的 nuget 包引用添加;在记录的情况下,这可能需要
IsExternalInit
,PMF 向您展示如何定义 - 一些功能需要运行时功能,不能在早期框架上工作,例如新的默认接口实现功能
- 你 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
的某些版本