IEquatable,如何正确实现这一点

时间:2012-01-09 11:03:51

标签: c# .net c#-2.0

我正在使用.net 2.0和c#,我已经在我的类中实现了IEquatible接口: -

public MyClass() :  IEquatable<MyClass>
{
    Guid m_id = Guid.NewGuid();

    public Guid Id
    {
        get
        {
            return m_id;
        }
    }

    #region IEquatable<MyClass> Members

    public bool Equals(MyClass other)
    {
        if (this.Id == other.Id)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    #endregion
}

这是不好的编程习惯吗?我已经读过我还需要实现Object.Equals和Object.GetHashCode,但我不知道为什么。

我希望能够检查MyClass的实例是否已包含在MyClass类型的通用列表中。为什么框架只建议你只实现Equals?

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

您可以使用LINQ检查列表是否包含使用条件的自定义谓词的项目。在这种情况下,您无需覆盖Equals,也无需实施IEquatable

// check if the list contains an item with a specific ID
bool found = someList.Any(item => item.ID == someId);

如果您需要将商品存储在EqualsGetHashCode中,则覆盖IEquatable(使用Dictionary)并实施Hashtable非常有用。

答案 1 :(得分:0)

  

这是不好的编程习惯吗?

实施IEquatable<T>非常棒,对结构来说更是如此,但仅仅做这么多还不够。

  

我读过我还需要实现Object.Equals

Read it here why..

  

和Object.GetHashCode也是如此,但我不确定原因。

Read it herehere。说真的,这些已经讨论了很多次,而且非常简单..简而言之,你需要它来处理像Dictionary<,>HashSet<>

这样的哈希的集合类型
  

我希望能够检查MyClass的实例是否已包含在MyClass类型的通用列表中。为什么框架只建议你只实现Equals?

取决于收藏类型。对于List<T>,它仅根据您定义Equals方法的方式检查相等性,例如Contains方法。对于大多数情况,您只需要Equals。但是如果你有一个HashSet<T>那么缺席和存在检查会利用你对象的哈希值。框架确实要求我们实现良好的哈希方法(不重新发明轮子)at appropriate places

  

非常感谢任何帮助。

执行以下操作,但只有在对您有意义的情况下才必须重置运算符==!=。看到你的课我认为你的班级有价值语义。否则只是忽略该部分(如果==应该表示引用相等)...从你的guid获取hashcode就足够了,只要你需要测试相等性。

public sealed class MyClass : IEquatable<MyClass>
{
    Guid m_id = Guid.NewGuid();

    public Guid Id { get { return m_id; } }

    public bool Equals(MyClass other)
    {
        if (ReferenceEquals(this, other))
            return true;

        if (ReferenceEquals(null, other))
            return false;

        return Id == other.Id; 
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as MyClass);
    }

    public static bool operator ==(MyClass lhs, MyClass rhs)
    {
        if (ReferenceEquals(lhs, null))
            return ReferenceEquals(rhs, null);

        return lhs.Equals(rhs);
    }

    public static bool operator !=(MyClass lhs, MyClass rhs)
    {
        return !(lhs == rhs);
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }   
}

为了避免错误,请使用可用的代码段here :为了更好地了解see this SO thread.