.net core 中是否有 public MemberNotNull/MemberNotNullWhen 属性

Are there any public MemberNotNull/MemberNotNullWhen attributes in .net core

不久前,我阅读了以下关于 C# 8 中的可空引用分析的文章: https://www.meziantou.net/csharp-8-nullable-reference-types.htm

post-condition 属性对我来说特别有趣。最近我遇到了一个情况,应用 MemberNotNull 属性可能会有用。但是,出乎意料的是,我在.Net core 3.1中找不到MemberNotNullMemberNotNullWhenpublic属性。但是,我可以看到许多在 .net core 中声明的内部属性: https://source.dot.net/#q=MemberNotNull

.net core 中是否有这些属性的任何替换。我必须使用 .net 5 才能使用它们吗?

我试图将这两个属性的声明复制到我的源代码中,但是当我在我的自定义命名空间中声明属性时它没有帮助。但是,如果我像这样在 System.Diagnostics.CodeAnalysis 命名空间中声明它们,那么它会起作用:

namespace System.Diagnostics.CodeAnalysis
{
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
    public sealed class MemberNotNullWhenAttribute : Attribute
    {
        /// <summary>Initializes the attribute with the specified return value condition and a field or property member.</summary>
        /// <param name="returnValue">
        /// The return value condition. If the method returns this value, the associated parameter will not be null.
        /// </param>
        /// <param name="member">
        /// The field or property member that is promised to be not-null.
        /// </param>
        public MemberNotNullWhenAttribute(bool returnValue, string member)
        {
            ReturnValue = returnValue;
            Members = new[] { member };
        }

        /// <summary>Initializes the attribute with the specified return value condition and list of field and property members.</summary>
        /// <param name="returnValue">
        /// The return value condition. If the method returns this value, the associated parameter will not be null.
        /// </param>
        /// <param name="members">
        /// The list of field and property members that are promised to be not-null.
        /// </param>
        public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
        {
            ReturnValue = returnValue;
            Members = members;
        }

        /// <summary>Gets the return value condition.</summary>
        public bool ReturnValue { get; }

        /// <summary>Gets field or property member names.</summary>
        public string[] Members { get; }
    }
}

并且 Roslyn 删除了针对可能的 null 取消引用显示的警告。 但是,我收到以下错误:

Error CS8652: The feature 'MemberNotNull attribute' is currently in Preview and unsupported. To use Preview features, use the 'preview' language version.

所以看来我至少可以通过这种方法切换到预览语言版本。但我想避免这样的黑客攻击,所以如果有更好的解决方案请提供,我会将其标记为已接受的答案。

编辑:为了避免评论中表达的一些混淆 - 这个答案允许使用 MemberNotNullWhen 属性而不会出现编译时错误。只需添加

  <LangVersion>preview</LangVersion>

到您的项目文件。

您可以参考Nullable包。它的作用与您使用复制粘贴所做的基本相同。认为这是将这些属性反向移植到 .net50 之前的 sdks 的最佳方式。

如果您不想升级您的框架版本,或者不想从 .NET 5 向后移植 [MemberNotNull] 支持,您可以使用 null 宽容运算符来初始化相关字段作为解决方法。

例如,如果您有一个在方法 Init() 中初始化的不可为 null 的字段 _myField,您可以在构造函数中添加写入以下内容以删除有关非空字段的警告退出构造函数时为空值。

_myField = null!;
InitFields();