IEquatable,如何正确实施

发布于 2024-12-25 10:44:16 字数 675 浏览 1 评论 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?

任何帮助将不胜感激。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余生一个溪 2025-01-01 10:44:16

您可以使用 LINQ 检查您的列表是否包含使用自定义谓词作为条件的项目。在这种情况下,您不需要重写 Equals 也不需要实现 IEquatable

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

重写 Equals (使用 GetHashCode)并且如果您需要将项目存储在 DictionaryHashtable 中,那么实现 IEquatable 会非常有用。

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.

忱杏 2025-01-01 10:44:16

这是不好的编程习惯吗?

实现 IEquatable非常棒,对于结构体来说更是如此,但仅仅做到这么多还不够。

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

在这里阅读为什么..

还有 Object.GetHashCode,但我不知道为什么。

在此处阅读并<一href="https://stackoverflow.com/questions/2265503/why-do-i-need-to-override-the-equals-and-hashcode-methods-in-java">此处。说真的,这些已经讨论过很多次了,而且非常简单。简而言之,您需要它来处理诸如 Dictionary<,>HashSet<> 等哈希值的集合类型;

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

取决于集合类型。对于 List,它将仅根据您定义的 Equals 方法(例如 Contains 方法)来检查相等性。对于大多数情况,您只需要Equals。但是,如果您有一个 HashSet,则缺席和存在检查将利用对象的哈希值。框架确实要求我们实现良好的哈希方法(无需重新发明轮子)在适当的地方

任何帮助将不胜感激。

执行如下操作,但仅当对您有意义时才必须重载运算符 ==!=。看到你的类,我认为你的类可以具有值语义。否则,只需忽略该部分(如果 == 应该意味着引用相等)...从您的 guid 获取哈希码就足够了,前提是您需要测试相等性。

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

为了避免出错,请使用此处提供的代码段:以获得良好的概述< a href="https://stackoverflow.com/questions/104158/what-is-best-practice-for-comparing-two-instances-of-a-reference-type">请参阅此线程。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文