gpt4 book ai didi

C# 基于简单值的 DTO 比较(和 GetHashCode 困境)

转载 作者:行者123 更新时间:2023-11-30 12:10:15 25 4
gpt4 key购买 nike

我知道已经有很多关于 GetHashCode 的讨论,但是他们通常提供的建议对于解决本应相对简单的问题并不是很有帮助...

我有一个简单的 DTO 类,它有许多不同类型的自动实现的属性,我想对这个类的两个实例执行一个简单的基于值的比较。 (主要目的是确定在不同时间点生成的实例之间发生的任何变化。)

这可以通过添加适当的方法很容易地完成。但碰巧的是,这正是 Equals() 方法和 IEquatable 接口(interface)的用途。所以我认为与其仅仅实现一个非标准的自定义方法,不如实现 IEquatable 更有意义......

现在问题来了:MSDN 文档说,为了实现 IEquatable,您还应该覆盖 Object.Equals()。这是有道理的。但是,如果您覆盖 Object.Equals(),您也应该覆盖 HetHashCode()。仍然不是真正的问题,我在这里找到了关于如何计算它的各种讨论,如果你决定的话。

但是我读过的文档和此处的所有讨论都说 GetHashCode() 输出应该保持稳定,因此不建议在可变对象上覆盖它……我可以理解这一点。 (不过,请注意,我无意将此类用作字典键,这似乎是主要问题...)

但是我拥有的 DTO 类是可变的。让它不可变将需要使用笨拙的构造函数或带有大量参数的静态工厂方法或构建器模式,并且会阻止您使用相当方便的对象初始化语法。总而言之,这真的不值得付出努力和带来不便。

那现在呢?我仍然想添加一种比较内容的方法,但现在我不太确定推荐的最佳做法是什么。

编辑:

忘了补充一点,我还看到了关于基于您类(class)中的一组不可变字段实现 GetHashCode 的建议。然而,由于我所有的属性都是自动实现和可设置的,从技术上讲,它们都可以改变......

更新:

感谢您的回答。所以基本上我不需要太担心 GetHashCode,只要“我知道我在做什么”——这意味着该类不会在键控集合中使用。

也感谢有关 IEqualityComparer 的建议,我可能会试一试。

选择“接受”的答案有点困难,因为它们都是很好的答案,但我必须选择一个...

最佳答案

有人可能会认为您的 DTO 根本不应该有任何行为,包括 EqualsGetHashCode。如果要比较这些类型的对象,请使用您在其他地方定义的方法。这很好地解决了这个问题。

但假设您对 DTO 没有那么严格,那么您必须覆盖 Equals(Object)。您不一定非要实现 IEquatable,但如果您愿意,也可以。而且,是的,如果您覆盖 Equals(Object),那么您确实应该覆盖 GetHashCode

是的,GetHashCode 依赖于可变字段通常不是一个好主意。但是,如果您不会在键控集合中使用对象,则不必担心。继续做你需要做的事。请记住:MSDN 中的准则是准则。如果您了解规则并了解违反规则的风险 - 并且您愿意承担后果 - 那么就去行动吧。

关于C# 基于简单值的 DTO 比较(和 GetHashCode 困境),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18895947/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com