如果散列中有一个或多个字段,则使用 HashSet 和 Contains 返回 TRUE

Z0R*_*RrO 1 c# hashset

我想知道是否可以使用 HashSet 并使方法Contains返回 true 如果字段之一在给定对象的哈希中。

这是我想要的一个例子

static void Main(string[] args)
{
    HashSet<Product> hash = new HashSet<Product>();

    // Since the Id is the same, both products are considered to be the same even if the URI is not the same
    // The opposite is also true.  If the URI is the same, both products are considered to be the same even if the Id is not the same
    Product product1 = new Product("123", "www.test.com/123.html");
    Product product2 = new Product("123", "www.test.com/123.html?lang=en");

    hash.Add(product1);

    if (hash.Contains(product2))
    {
        // I want the method "Contains" to return TRUE because one of the field is in the hash
    }
}
Run Code Online (Sandbox Code Playgroud)

这是 Product 类的定义

public class Product
{
    public string WebId
    public string Uri

    public Product(string Id, string uri)
    {
        WebId = Id;
        Uri = uri;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != typeof(Product)) return false;
        return Equals((Product)obj);
    }

    public bool Equals(Product obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;

        if (String.Equals(WebId, obj.WebId) || String.Equals(Uri, obj.Uri)) 
            return true;
        else
            return false;
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = 17;

            hash = hash * 23 + WebId.GetHashCode();
            hash = hash * 23 + Uri.GetHashCode();
            return hash;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行我的程序时,方法Contains只运行GetHashCode而从不运行方法Equals。因此,方法Contains返回 FALSE。

我怎样才能让我的 HashSet 为上面的例子返回 TRUE?我应该改用字典并将每个字段添加到字典中吗?

Han*_*ant 5

您的 GetHashCode() 实现不能保证为两个相等的对象返回相同的值。因为你只需要匹配,比如说,WebId。然后 Uri 搞砸了哈希码。或者反过来。除了返回 0 之外,您无法解决此问题。这将杀死 HashSet<> 性能,查找将是 O(n) 而不是 O(1)。