【问题标题】:C# Generic Method with non-nullable generic parameter warns of possible null reference具有不可为空泛型参数的 C# 泛型方法警告可能的空引用
【发布时间】:2021-06-11 10:09:06
【问题描述】:

今天在编程时出现了以下情况。 泛型方法接受不可为空的泛型参数。该方法基本上只是将通用值插入到集合中。但是,这会引发编译器警告,指出泛型参数可能为空。从表面上看,这似乎是编译器中的一个错误,并且与可空值的设计相矛盾。但是,我确信有一些我没有看到的很好的解释。

考虑以下情况的简化示例: public void M1<T>(T t, List<object> l) => l.Add(t); 编译器警告l.Add(t) 中的 t 可能为空。

也只是为了完整性,以下方法给出了相同的错误(如预期的那样): public void M1<T>(T? t, List<object> l) => l.Add(t);

有人对此有很好的见解吗?

【问题讨论】:

    标签: c# generics nullable nullable-reference-types


    【解决方案1】:

    有人可以打电话:

    var list = new List<object>();
    M1<string?>(null, list);
    

    现在您的列表应该只包含不可为空的对象,现在包含null。因此发出警告。

    如果你想防止 T 成为可空类型,那么:

    public void M1<T>(T t, List<object> l) where T : notnull
    {
        ...
    }
    

    这会给你警告:

    M1<string?>(null, new List<object>());
    ^^^^^^^^^^^
    // warning CS8714: The type 'string?' cannot be used as type parameter 'T' in the generic 
    // type or method 'C.M1<T>(T, List<object>)'. Nullability of type argument 'string?' doesn't
    // match 'notnull' constraint.
    

    如果您想让T 成为null,但仍然禁止该t 参数的null 值,则:

    public void M1<T>([DisallowNull] T t, List<object> l)
    {
        ...
    }
    

    这会给你警告:

    M1<string?>(null, new List<object>());
                ^^^^
    // warning CS8625: Cannot convert null literal to non-nullable reference type.
    

    当然,如果您想允许null,那么您的l 必须是List&lt;object?&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-14
      • 2021-02-17
      • 2020-03-31
      相关资源
      最近更新 更多