代码之家  ›  专栏  ›  技术社区  ›  jwatts1980

可能的空引用分配/杂注警告禁用

  •  0
  • jwatts1980  · 技术社区  · 2 年前

    我有一个特殊的泛型类,它包含一个复杂的对象集合。我正在创建一个扩展方法来搜索类,看看是否存在按名称命名的特定项。值得注意的是,这种类型 T 没有任何特定的限制。它可以是类/引用类型、数字类型或字符串。

    我的扩展方法如下所示:

    public static bool TryGetItem<T>(this MySpecialClass<T> msc, string name, out T item)
    {
        T? i = msc.FindItemByName(name);
        if (i != null) 
        {
            item = i;
            return true;
        }
        else 
        {
            item = default(T);  //warning on this line.
            return false;
        }
    
    

    如果不明显,扩展方法的用例如下:

    //Example if the class is holding integers.
    if (msc1.TryGetItem("somename1", out int item)
    {
        //do something with 'item'
    }
    
    //Example if the class is holding MyClass1 objects
    if (msc2.TryGetItem("somename2", out MyClass1 item)
    {
        //do something with 'item'
    }
    

    我在Visual Studio 2022中使用Core 6,并且启用了“nullable”选项。结果,我在 item = detault(T); 台词

    可能的空引用分配。

    我明白为什么我会收到警告:我正在分配 default(T) item 其不被标记为可为null。但该方法的本质是 out 如果方法返回,则永远不会使用值 false 显然,VS没有意识到这一点,省略这一行会导致错误,因为 出来 必须将参数分配给。

    这是在一个扩展方法中,我可以忽略这条歪歪扭扭的线,但我打开null选项是有原因的,因为我相信这会迫使我创建更健壮的代码。所以,我想知道我是否错过了一个更好的方法来处理这个问题。

    现在,我强制VS2022跳过警告,像这样换行以将其从中删除 警告列表:

    #pragma warning disable CS8601
        item = default(K);
    #pragma warning restore CS8601
    

    但我无法摆脱这样一种感觉,即我正在做一些“古怪”的事情。有没有一种标准的方式让我来处理这个问题?或者这种情况是“#pragma warning disable/restore”的一个很好的用法?

    1 回复  |  直到 2 年前
        1
  •  2
  •   Sweeper    2 年前

    您应该使用属性 MaybeNullWhenAttribute .

    标记 out 参数带有 [MaybeNullWhen(false)] :

    public static bool TryGetItem<T>(
        this MySpecialClass<T> msc, 
        string name, 
        [MaybeNullWhen(false)] out T item
    ) {
        ...
    }
    

    虽然 item 是用不可为null的类型声明的,属性告诉编译器它 也许 TryGetItem 返回false。

    另请参阅 this section 在关于可为null的分析属性的文档中。