【问题标题】:Reference types with value semantics and equality operator具有值语义和相等运算符的引用类型
【发布时间】:2013-08-20 17:50:47
【问题描述】:

Link:

• 考虑在引用类型上覆盖 Equals,如果 该类型基于该类型表示某些值这一事实。

• 大多数引用类型不得重载相等运算符,即使 如果他们覆盖 Equals。但是,如果您正在实施参考 旨在具有值语义的类型,例如复杂的 number 类型,你必须重写相等运算符。

a) 据我了解,要使引用类型的不同实例可互换,我们应该同时覆盖 Equals 方法和 equality operator 并使类型不可变

b) 具有值语义的 引用类型 是否表明该类型的不同实例(表示相同值)应该是可互换的?

c) 但是根据上面的引用,某些具有值语义的引用类型应该只覆盖Equals 方法,但不能覆盖equality operator。我们怎么能声称这些类型具有值语义,因为该类型的实例显然不可互换?

d) 那么我们基于什么标准来决定一个具有值语义的引用类型是应该只覆盖其Equals方法还是覆盖其equality operator?仅仅基于我们是否愿意使类型不可变?

感谢

【问题讨论】:

标签: c#


【解决方案1】:

关于 A 点,是的,类型应该是不可变的。来自MSDN

您不应在可变引用类型上覆盖 Equals。

我认为 D 是这里的核心问题,framework design guidelines 似乎表明这归结为性能:

避免在引用类型上重载相等运算符,如果 实施将明显慢于参考 平等。

Eric Lippert 对此here 有一些有趣的看法。我最喜欢的一句话是:

长的答案是整个事情都很奇怪,而且两者都不起作用 理想情况下应该这样做。

就我个人而言,这让我松了一口气,因为我一直认为“==”在功能上是 Equals() 的可读简写(尽管我知道它不是)。

【讨论】:

  • 请注意,有时您可能希望对可变引用类型的值进行比较。要解决这些问题,您可以为具有值语义的该类型使用 IEqualityComparer,如果在特定上下文中使用它是合适的。
  • 所以我们多久需要一次不同的值(因此需要用另一个值对象替换一个值对象)在决策中并不重要,即使对象创建很昂贵?同样,它是否也可能取决于我们使用的设计技术(例如领域驱动设计)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-12
  • 2012-01-27
  • 2022-01-17
  • 2015-06-05
  • 2019-11-12
  • 1970-01-01
相关资源
最近更新 更多