gpt4 book ai didi

c# - IEquatable、IComparable 是否应该在非密封类上实现?

转载 作者:IT王子 更新时间:2023-10-29 04:02:45 25 4
gpt4 key购买 nike

大家有没有意见IEquatable<T>IComparable<T>通常应该要求 Tsealed (如果它是 class )?

我想到了这个问题,因为我正在编写一组旨在帮助实现不可变类的基类。基类旨在提供的部分功能是相等比较的自动实现(使用类的字段以及可应用于字段以控制相等比较的属性)。当我完成时它应该非常好 - 我正在使用表达式树为每个 T 动态创建一个编译比较函数,因此比较函数应该非常接近常规相等比较函数的性能。 (我正在使用以 System.Type 为键的不可变字典并仔细检查锁定以合理执行的方式存储生成的比较函数)

不过突然出现的一件事是使用什么函数来检查成员字段的相等性。我的初衷是检查每个成员字段的类型(我称之为 X )是否实现了 IEquatable<X> .但是,经过一番思考,我认为除非X,否则使用起来不安全。是sealed .原因是如果X不是 sealed ,我不确定是否X适本地将相等性检查委托(delegate)给 X 上的虚方法,从而允许子类型覆盖相等比较。

这就提出了一个更普遍的问题——如果一个类型不是密封的,它真的应该实现这些接口(interface)吗??我不这么认为,因为我认为接口(interface)契约是在两个 X 之间进行比较。类型,而不是可能是也可能不是 X 的两种类型(尽管它们当然必须是 X 或一个子类型)。

大家怎么看?应该IEquatable<T>IComparable<T>避免使用未密封的类(class)? (也让我想知道是否有一个 fxcop 规则)

我目前的想法是让我生成的比较函数只使用 IEquatable<T>在其 T 的成员字段上是sealed , 而不是使用虚拟 Object.Equals(Object obj)如果T即使 T 也未密封工具 IEquatable<T> ,因为该字段可能存储 T 的子类型我怀疑 IEquatable<T> 的大多数实现为继承而设计。

最佳答案

我一直在思考这个问题,经过一番考虑后,我同意实现 IEquatable<T>IComparable<T>应该只对密封类型进行。

我来回想了一会儿,然后想到了以下测试。在什么情况下以下应该返回 false?恕我直言,2 个对象要么相等,要么不相等。

public void EqualitySanityCheck<T>(T left, T right) where T : IEquatable<T> {
var equals1 = left.Equals(right);
var equals2 = ((IEqutable<T>)left).Equals(right);
Assert.AreEqual(equals1,equals2);
}

IEquatable<T> 的结果在给定对象上应具有与 Object.Equals 相同的行为假设比较器是等效类型。实现 IEquatable<T> twice in an object hierarchy 允许并暗示在您的系统中有两种不同的表达相等性的方式。设计任意数量的场景很容易 IEquatable<T>Object.Equals会有所不同,因为有多个 IEquatable<T>实现,但只有一个 Object.Equals .因此,上面的代码会失败并在您的代码中造成一些困惑。

有些人可能会争辩说实现IEquatable<T>在对象层次结构的较高位置是有效的,因为您要比较对象属性的子集。在那种情况下,你应该喜欢 IEqualityComparer<T>它专门用于比较这些属性。

关于c# - IEquatable<T>、IComparable<T> 是否应该在非密封类上实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1868316/

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