在 setter 上停止 C# 警告“可能的 Null 引用赋值”,该警告处理不可为 null 类型的 null 值

Stop C# warning "Possible Null Reference Assignment" on setter which handles null values for a not nullable type

提问人:user3797758 提问时间:2/22/2023 最后编辑:user3797758 更新时间:2/22/2023 访问量:477

问:

public class Example
{
    public string Name
    {
        get => m_name;
        set => m_name = value ?? string.Empty; // valid to assign null cause it's handled but caused warnings
    }
    private string m_name;

    public Example(string? name)
    {
        Name = name; // CS8601 - Possible null reference assignment.
    }
}

// imagine this is setting on an instance and not the type
Example.Name = data; // CS8601 - Possible null reference assignment.

在代码中,我有一个从不为 null 的类型,因为它属性设置器将 null 赋值转换为默认值。编译器不明白这一点,并为此抱怨。string

我知道我可以通过以下方式解决其中的一些问题:

  • 放在赋值之后,因为我比编译器更了解 - 不喜欢这样,因为它可能会因重构而中断!
  • 在构造函数中,分配后备字段而不是属性 - 有效,但复制构造函数中的回退代码,并且再次意味着如果重构/更改,则必须更新多个位置
  • 将 type 更改为 - 在这些情况下有效,但会向所有尝试获取值的位置添加编译器警告,这可能超过设置属性!Namestring?

有没有办法修复这个不黑客的警告?

例如,告诉 setter 赋值可以是,或者添加一个与您可以在 on 方法上使用的样式相同的属性?null[MaybeNullWhen(false)]TryGet

我找不到不涉及代码重复或忽略编译器的问题的修复方法

C# null 编译器警告

评论


答:

5赞 Sweeper 2/22/2023 #1

这是 AllowNullAttribute 的用例。此处的文档显示了非常相似的情况。

你只需要做:

using System.Diagnostics.CodeAnalysis;

// ...

[AllowNull]
public string Name
{
    get => m_name;
    set => m_name = value ?? string.Empty;
}

然后,可以为此属性分配一个可为 null 的类型。

如果要设置属性而不是构造函数中的字段,则还应该使用 标记 setter,以便静态分析器可以看到您已初始化构造函数中所有不可为 null 的字段。MemberNotNullAttribute

[MemberNotNull("m_name")]
set => m_name = value ?? string.Empty;

评论

0赞 user3797758 2/23/2023
我就知道会有这样的事情,只是不知道会是什么样子!谢谢