IEquatable, how to implement this properly [duplicate]

…衆ロ難τιáo~ 提交于 2020-05-09 07:04:32

问题


I am using .net 2.0 and c# and I have implemented the IEquatible interface in my class like this:-

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
}

Is this bad programming practice? I've read that I also need to implement Object.Equals and Object.GetHashCode as well, but I am not sure why.

I want to be able to check that an instance of MyClass is not already contained in a generic list of type MyClass. Why does the framework only suggests that you implement Equals only?

Any help would be greatly appreciated.


回答1:


You can check if your list contains an item using a custom predicate for the criteria, using LINQ. In that case you don't need to override Equals nor implement IEquatable:

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

Overriding Equals (with GetHashCode) and implementing IEquatable is useful if you need to store your item in a Dictionary or a Hashtable.




回答2:


Is this bad programming practice?

Implementing IEquatable<T> is great, even more so for structs, but merely doing that much is not enough.

I've read that I also need to implement Object.Equals

Read it here why..

and Object.GetHashCode as well, but I am not sure why.

Read it here and here. Seriously, these have been discussed so many times, and it is pretty simple.. In short, you need it for collection types that deals with hashes like Dictionary<,> or HashSet<>

I want to be able to check that an instance of MyClass is not already contained in a generic list of type MyClass. Why does the framework only suggests that you implement Equals only?

Depends on the collection type. For a List<T>, it will check equality merely based on how you have defined Equals method, say for Contains method. For most scenario you will need Equals only. But if you have a HashSet<T> then absence and presence checks will utilize hash of your objects. Framework indeed asks us to implement good hashing approaches (without re-inventing the wheel) at appropriate places.

Any help would be greatly appreciated.

Do as below, but you have to overload operators == and != only if it make sense to you. Seeing your class I assumed its ok to have value semantics for your class. Otherwise just ignore that part (if == should mean reference equality)... Getting hashcode from your guid would suffice, provided that is all you need to test equality.

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();
    }   
}

To not get it wrong, make use of the snippet available here: For a good overview see this SO thread.



来源:https://stackoverflow.com/questions/8787400/iequatable-how-to-implement-this-properly

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!