我有一些如下的类,我几乎对所有的类都实现了Equals(Object)方法。但是我不知道如何写GetHashCode()。就我在Dictionary集合中使用这些数据类型作为值类型而言,我认为我应该覆盖GetHashCode()

1.我不知道如何用GetHashCode()的逻辑实现Equals(Object)

2.有一些派生类,如果我为基类(GetHashCode())覆盖Equals(Object)Param,是否仍然有必要为 child 覆盖它?

class Param
{
    ...
    public Int16 id { get; set; }
    public String name { get; set; }
    ...
    public override bool  Equals(object obj)
    {
        if ( obj is Param){
            Param p = (Param)(obj);
            if (id > 0 && p.id > 0)
                return (id == p.id);
            else if (name != String.Empty && p.name != String.Empty)
                return (name.equals(p.name));
            else
                return object.ReferenceEquals(this, obj);
        }
        return false;
    }
}
class Item
{
    public int it_code { get; set; }
    public Dictionary<String, Param> paramAr { get; set; }
    ...
    public override bool Equals(Object obj)
    {
        Item im = new Item();
        if (obj is Item)
            im = (Item)obj;
        else
            return false;

        if (this.it_code != String.Empty && im.it_code != String.Empty)
            if (this.it_code.Equals(im.it_code))
                return true;

        bool reParams = true;
        foreach ( KeyValuePair<String,Param> kvp in paramAr ){
            if (kvp.Value != im.paramAr[kvp.Key]) {
                reParams = false;
                break;
            }
        }
        return reParams;
    }
}
class Order
{

    public String or_code { get; set; }
    public List <Item> items { get; set; }
    ...
    public override bool Equals( Object obj ){
        Order o = new Order();
        if (obj is Order)
            o = (Order)obj;
        else
            return false;

        if (this.or_code != String.Empty && o.or_code != String.Empty)
            if (this.or_code.Equals(o.or_code))
                return true;
        bool flag = true;
        foreach( Item i in  items){
            if (!o.items.Contains(i)) {
                flag = false;
                break;
            }
        }
        return flag;
    }
}

编辑:
我得到这个警告:

最佳答案

首先,据我所知,无论在哪里实现Equals,都必须也实现GetHashCodeGetHashCode实现必须反射(reflect)Equals实现的行为,但通常不使用它。

参见http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx-特别是“实现者注意事项”

因此,如果以ItemEquals实现为例,则您正在考虑idname的值都影响相等性。因此,这两个都必须有助于GetHashCode的实现。

下面是一个如何为GetHashCode实现Item的示例(请注意,您可能需要使其对可为空的name字段具有弹性):

public override GetHashCode()
{
    return id.GetHashCode() ^ name.GetHashCode();
}

请参阅Eric Lippert的博客文章,了解GetHashCode的准则-http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/

至于是否需要在子类中重新实现GetHashCode-是,如果您还覆盖Equals-按照第一个(和主要)要点-两者的实现必须一致-如果Equals认为两项相等,则它们必须从GetHashCode返回相同的值。

边注:
为了提高代码的性能(避免多次强制转换):
if ( obj is Param){
    Param p = (Param)(obj);

Param p = obj as Param;
if (p != null) ...

关于c# - 如何使用重写的Equals()的逻辑实现GetHashCode()的重写,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9827911/

10-13 04:52