ReSharper 5.x、HashSet Contains() 和 "Possible 'null' assignment"

4
这段代码输出True
using System;
using System.Collections.Generic;

public class Default
{
    public static void Main(string[] args)
    {
        HashSet<string> foo = new HashSet<string>();
        foo.Add(null);
        Console.WriteLine(foo.Contains(null));
    }
}

我的Contains()调用中的null下面有一个蓝色波浪线,显示以下警告信息:

可能将 'null' 分配给带有 'NotNull' 属性的实体

当我暂停使用ReSharper时,警告消息消失了。
为什么会出现这个警告?因为我可以向HashSet添加null,那么我想在HashSet中检查null有什么问题? 编辑:.NET 3.5,VS2010。

ReSharper似乎出了问题。其他方面都没问题:您的代码运行没有异常,Reflector也没有显示HashSet<T>.Add或HashSet<T>.Contains的任何null检查或NonNull属性。 - dtb
你真的应该将 Null 添加到 HashSet 吗? - Mitch Wheat
在我的真实代码中,Contains(null)的作用是验证在开发者有可能这样做的时刻,是否已经将null添加到HashSet中的规范。 - lance
ReSharper 出 bug 了!天哪!从没见过这样的事... - Coxy
2个回答

3
我认为这是Resharper中的一个bug。 HashSet<T>类型被构造用于处理null值。通过检查反射器中的代码,可以看出这一点。特别是InternalGetHashCode方法,它具有对null的显式检查,并提供默认哈希码0。
唯一可能出现问题的情况是,当自定义的IEqualityComparer<T>实例传递给HashSet<T>时,它没有考虑null值。不过我认为这种情况相当少见,因为在.Net中,对于引用类型,null检查是标准相等性模式的一部分。
注意:明确地说,我当然不鼓励人们将null添加到他们的集合中。事实上,我会鼓励相反的做法。只是指出,由于某种原因,HashSet<T>似乎明确允许这种情况。

仅仅因为你可以添加Null并不意味着这是一个好主意 ;) - Mitch Wheat
@Mitch,我并没有说这是一个好主意,只是HashSet<T>显然认为允许糟糕的代码;) - JaredPar

0
我怀疑这可能是因为 HashSet<T>.Contains 方法是 ICollection<T>.Contains 的一种实现。
其他的 ICollection<T> 实现可能不允许为空值。
无论是否属实,也没有理由不对 ReSharper 规则集进行优化,以避免将此标记为潜在错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接