c# - 是否可以将 C#11 'required' 修饰符用于 .NET Framework 4.8 和 .Net Standard 2.0?

标签 c# .net

我希望能够使用 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 或更高版本进行编译。
  • 这些项目需要将语言版本指定为 11latest使用 <LangVersion>11</LangVersion><LangVersion>latest</LangVersion> .
  • 您不应公开任何使用 required 的公共(public)类型通过 NuGet 包修改器。
  • 不支持这种方法,它可能会在未来的版本中停止工作(我认为这不太可能,但不能保证它会一直有效)。

引用资料:

关于c# - 是否可以将 C#11 'required' 修饰符用于 .NET Framework 4.8 和 .Net Standard 2.0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74447497/

相关文章:

c# - 选择使用 .Net 4

c# - 如何将 List<object> 动态绑定(bind)到 WPF 中的 DataGrid?

c# - C# 构造函数 extern 修饰符的用途

C# Invalidate 不调用 paint 方法

c# - MVC 5 自定义 ViewEngine 加载外部 Controller 和 View

c# - Unity XML 从 xml 列表中获取列表值到 c# 列表

c# - 如何为没有 x 值的一系列数据创建箱线图

c# - 如何确定上传的文件是 UTF-8 还是 UTF-16?

c# - ASP.NET MVC 如何在我的 View 文件夹中注册一个资源文件,用作@using

c# - 日期时间.TryParse -> "Ghost ticks"