所以我有一个值object
,(任意说钱),我想为它实现平等。 我知道==
和.Equals()
的预期/默认行为(参考和数据相等)。
不过在这种情况下,我希望能够比较两个物体,并说它们对于计算是等效的(例如,1m 和 3 ft 是等效的)但是对于持久性(使用NHibernate
,我认为isDirty
取决于相等)、用户显示和货币选择,我希望它们被认为是不同的。
在这种情况下,我应该
- 对
==
和.Equals()
有不同的行为(以及哪个应该做什么), - 无论我想检查等效性在哪里,只需检查每个属性(意味着额外的代码)
- 实现像
.IsEquivalent()
这样的方法(我不想做后者) - 我缺少的其他东西
是否有我应该遵循的最佳实践/模式?谢谢
编辑:我收到了一些关于改变汇率的回复。所以更新是为了清楚起见。让我们说身高,而不是货币
- 我想澄清一些假设:
- 忽略:值对象包含十进制金额、字符串/类货币
- 忽略:汇率不会改变。
- 忽略:类货币知道其往返于另一个货币的汇率
- 值对象包含十进制数量、字符串/类单位
- 类单元知道它与另一个类单元之间的转换
- 我不打算扩大费率/转换等
我更关心的是实践和模式,而不是实施货币。基本上,一个人的身高方法相同,其中身高是一个值对象,({1,m} 到 {3,ft},其中 1m 总是"等于"/"等价"到 3ft)
我不会将 1.0 美元视为等于 0.63 英镑。 为了检查货币价值的相等性,您需要的信息不仅仅是两个值 - 您还需要当前汇率等。 尤其如此,因为相同的两个值不会始终相等,如果两个值永远相等,则相等应始终为真。
因此,一种方法(例如 AreEquivalentMonitaryValues()
)似乎是合适的 - 特别是考虑到需要额外的信息。
由于您希望根据上下文对相等有不同的定义,因此您希望使用IEqualityComparer
。
正如里德所建议的那样,类型本身的平等实际上应该意味着"永远和永远是平等的",而不是当前汇率的平等,但拥有一个IEqualityComparer只是意味着,"从这个比较器的角度来看,它们是平等的"。 从那里,您可以让ExchangeRate
类型或给定汇率的东西能够创建一个表示给定汇率相等的IEqualityComparer<Money>
对象。 然后,该相等比较器可用于比较各种类型的货币的相等性。
另一种方法是创建一个"不变货币",并为你的类提供ToInvariant
和FromInvariant
方法,以便非不变货币不相等(永远),并且不变货币可以相等,尽管生成不变值的货币
创建一个具有方法IsWorthApproximatelyTheSame(Money m1, Money m2)
的类MoneyExchangeRates
。
汇率随时间而变化,不要使它们成为全局可变状态。