Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#DTO的简单基于值的比较(和GetHashCode dilema)_C# - Fatal编程技术网

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

C#DTO的简单基于值的比较(和GetHashCode dilema),c#,C#,我知道已经有很多关于GetHashCode的讨论,但是他们通常提供的建议对于解决一个相对简单的问题不是很有帮助 我有一个简单的DTO类,它具有许多自动实现的各种类型的属性,我想在这个类的两个实例上执行一个简单的基于值的比较。(主要目的是确定在不同时间点生成的实例之间发生的任何更改。) 通过添加适当的方法,可以很容易地做到这一点。但事实上,这正是Equals()方法和IEquatable接口的用途。所以我认为,与其只是实现一个非标准的定制方法,不如实现IEquatable 现在问题来了:MSDN文

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

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

通过添加适当的方法,可以很容易地做到这一点。但事实上,这正是Equals()方法和IEquatable接口的用途。所以我认为,与其只是实现一个非标准的定制方法,不如实现IEquatable

现在问题来了:MSDN文档说,为了实现IEquatable,还应该重写Object.Equals()。这是有道理的。但如果重写Object.Equals(),也应该重写HetHashCode()。仍然不是一个真正的问题,我在这里发现了关于如何计算它的各种讨论

然而,我阅读的文档和这里的所有讨论都表明GetHashCode()输出应该保持稳定,因此不建议在可变对象上重写它。。。我能理解这一点。(尽管如此,让我注意到我并不打算使用这个类作为字典键,这似乎是主要的关注点…)

然而,我拥有的DTO类是可变的。使其不可变需要使用笨拙的构造函数或带有大量参数或构建器模式的静态工厂方法,并且会阻止您使用相当方便的对象初始值设定项语法。总而言之,这样的努力和不便实在不值得

那现在呢?我仍然想添加一个比较内容的方法,但现在我真的不确定推荐的最佳实践是什么

编辑:

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

更新:

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

另外,感谢您对iQualityComparer的建议,我可能会尝试一下


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

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

但是假设您对DTO没有那么严格,那么您必须重写
Equals(Object)
。您不必实现
IEquatable
,但如果需要,您可以实现。是的,如果您重写
Equals(Object)
,那么您确实应该重写
GetHashCode


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

只要对象用作哈希表中的键,哈希代码就需要稳定。如果您不将其用作密钥,或者在添加后不对其进行变异,那么就可以了

如果不将其用作哈希表键,则根本不需要重写
GetHashCode
。Resharper可以生成所有相等成员。这是我通常做的事。

请看