我希望能够使用 the new C#11 required
modifier使用 .NET Framework 4.8 和 .Net Standard 2.0。
我使用的是 Visual Studio 2022 版本 17.4。这可能吗?
最佳答案
这是可能的,但您必须提供编译器支持它所需的一些类型。您还需要使用 Visual Studio 2022 版本 17.4 或更高版本以及 C# 11 进行编译。
必要的类型在 .NET 7.0 中定义,但它们在早期版本中并不全部存在。这些类型如下:
-
static class IsExternalInit
- 在 C# 9 和 .NET 5 中引入。 -
class RequiredMemberAttribute
- 在 C# 11 和 .NET 7 中引入。 -
class CompilerFeatureRequiredAttribute
- 与 C# 11 一起引入,并且 .NET 7。
这些类型必须全部在 System.Runtime.CompilerServices
中定义命名空间。它们也应声明为 internal
- 如果它们是 public
并在 .NET 7 项目引用的类库中定义,您将遇到多重定义的错误。
您可以按如下方式声明它们 - 这必须包含在每个使用 required
的 .NET 4.8 或 .NET Standard 2.0 程序集中。修饰符:
using System.ComponentModel;
namespace System.Runtime.CompilerServices
{
#if !NET5_0_OR_GREATER
[EditorBrowsable(EditorBrowsableState.Never)]
internal static class IsExternalInit {}
#endif // !NET5_0_OR_GREATER
#if !NET7_0_OR_GREATER
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
internal sealed class RequiredMemberAttribute : Attribute {}
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
internal sealed class CompilerFeatureRequiredAttribute : Attribute
{
public CompilerFeatureRequiredAttribute(string featureName)
{
FeatureName = featureName;
}
public string FeatureName { get; }
public bool IsOptional { get; init; }
public const string RefStructs = nameof(RefStructs);
public const string RequiredMembers = nameof(RequiredMembers);
}
#endif // !NET7_0_OR_GREATER
}
namespace System.Diagnostics.CodeAnalysis
{
#if !NET7_0_OR_GREATER
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
internal sealed class SetsRequiredMembersAttribute : Attribute {}
#endif
}
注意 #if
的使用支持不同目标的指令。
(顺便说一句,internal static class IsExternalInit {}
的声明还允许使用 C# 9 中引入的 record
类型和 init only
属性 setter 功能。)
将上述定义添加到 .NET Framework 4.8 或 .NET Standard 2.0 程序集后,您可以使用 required
该程序集中的修饰符,即使该程序集被另一个不提供这些定义的 .NET Framework 4.8 或 .NET Standard 2.0 程序集引用(尽管您仍然需要提供其中的定义)其他程序集,如果您想对该程序集中定义的类使用 required
修饰符)。
注意事项:
- 所有使用
required
的 .NET Framework 4.8 或 .NET Standard 2.0 程序集修饰符必须使用 Visual Studio 2022 版本 17.4 或更高版本进行编译。 - 这些项目需要将语言版本指定为
11
或latest
使用<LangVersion>11</LangVersion>
或<LangVersion>latest</LangVersion>
. - 您不应公开任何使用
required
的公共(public)类型通过 NuGet 包修改器。 - 不支持这种方法,它可能会在未来的版本中停止工作(我认为这不太可能,但不能保证它会一直有效)。
引用资料:
- C# 9 Records and Init Only Settings Without .NET 5 - 这是一篇很好的博客文章,详细介绍了通过 NuGet 公开程序集的注意事项。这篇文章是关于 C# 9 的记录,但它也适用于此。
-
Required
modifer reference -required
的 Microsoft 文档.
关于c# - 是否可以将 C#11 'required' 修饰符用于 .NET Framework 4.8 和 .Net Standard 2.0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74447497/