按值相等的接口;不要改变开箱即用的行为

本文关键字:改变 接口 | 更新日期: 2023-09-27 18:24:41

好的,我正在阅读关于如何覆盖对象的所有建议。对于值和引用类型,等于和==。简而言之,总是重写结构的相等,不要重写引用类型的相等,除非您有一些特殊的情况,比如封装单个字符串的类。(但不要制作一个结构,除非它很小,即使在语义或DDD术语中它是一种值类型)

但我的大多数保存数据的类型都是DTOS——有很多属性的类。它们有更多适合结构的属性(超过16字节),并且将被期望==和object的开发人员使用。等于行为正常。这三种情况都出现了——需要通过引用、值(尤其是在单元测试中)和键(尤其是当处理来自或将要进入关系数据库的数据时)来检查相等性

有没有一种.NET框架方法可以在不影响对象默认行为的情况下实现按值相等或按键相等。等于?或者我必须创建自己的即席接口,如ISameByValue<T>ISameByKey<T>

按值相等的接口;不要改变开箱即用的行为

创建IEqualityComparer类型。这允许您创建任意数量的不同类型,这些类型能够通过任意数量的相等的不同定义来比较对象,而无需更改类型本身的任何行为。

我遇到了一个问题,我在重写的Equals方法中实现了基于属性的比较(以实现HasChanges类型功能),但当我更新集合中项的属性值时,它会导致各种问题。

我的解决方案(由本网站乐于助人的用户找到)是将基于属性的比较转移到一个新的自定义方法中,并返回默认的object.Equals值。然而,这意味着在调用Equals方法时不再有任何基于比较的方法。

然后,解决方案是提供IEqualityComparer<T>接口的自定义实现,并将实例传递给任何需要对象比较的方法,例如IEnumerable IntersectExcept方法:

if (digitalServiceProvider.PriceTiers[index].Territories.Count > 0 && 
    digitalServiceProvider.PriceTiers[index].Territories.Intersect(
    release.TerritorialRights, new CountryEqualityComparer()).Count() == 0) { ... }