Phi*_*hil 36 c# icomparable immutability sealed iequatable
任何人对是否有任何意见IEquatable<T>或IComparable<T>一般应要求T是sealed(如果是class)?
这个问题发生在我身上,因为我正在编写一组旨在帮助实现不可变类的基类.基类要提供的部分功能是自动实现相等比较(使用类的字段以及可应用于字段来控制相等比较的属性).当我完成时它应该是相当不错的 - 我正在使用表达式树为每个动态创建一个编译的比较函数T,因此比较函数应该非常接近正则相等比较函数的性能.(我使用键入的不可变字典System.Type和双重检查锁定以合理的方式存储生成的比较函数)
尽管如此,有一件事是用来检查成员字段相等性的函数.我的初衷是检查每个成员字段的类型(我将调用X)是否实现IEquatable<X>.但是,经过一番思考后,除非X是这样,否则我认为这是不安全的sealed.原因在于,如果X不是sealed,我无法确定是否X正确地将等式检查委托给虚拟方法X,从而允许子类型覆盖相等比较.
这就提出了一个更普遍的问题 - 如果一个类型没有被密封,它是否应该真正实现这些接口?我想不会,因为我认为接口契约是比较两种X类型,而不是两种类型,可能是也可能不是X(虽然它们当然必须是X或者是子类型).
你们有什么感想?应该IEquatable<T>和IComparable<T>避免对开封类?(也让我想知道是否有一个fxcop规则)
我现在的想法是让我产生比较功能只能用IEquatable<T>在成员字段,其T为sealed,而是用虚拟的Object.Equals(Object obj),如果T是密封的,即使T工具IEquatable<T>,因为该领域可能的潜在店亚型T和我怀疑的大多数实现IEquatable<T>适当设计的传承.
Jar*_*Par 20
我一直在考虑这个问题,经过一些考虑,我同意实施IEquatable<T>,IComparable<T>只应在密封类型上完成.
我来回走了一会儿然后我想到了下面的测试.在什么情况下,以下应该返回虚假?恕我直言,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);
}
Run Code Online (Sandbox Code Playgroud)
对于IEquatable<T>给定对象的结果应该具有与Object.Equals假设比较器是等效类型相同的行为.IEquatable<T>在对象层次结构中实现两次允许并且暗示在系统中有两种不同的表达相等的方式.这很容易图谋任意数量的场景中IEquatable<T>,并Object.Equals会不同,因为有多个IEquatable<T>实现,但只有一个Object.Equals.因此,上述操作会失败并在您的代码中造成一些混乱.
有些人可能会争辩说,IEquatable<T>在对象层次结构中的更高点实现是有效的,因为您想要比较对象属性的子集.在这种情况下,您应该支持IEqualityComparer<T>专门用于比较这些属性的.
我通常建议不要在任何非密封类上实现IEquatable <T>,或者在大多数情况下实现非通用IComparable,但对于IComparable <T>则不能这样说.两个原因:
在可继承类中实现非泛型IComparable可能比IComparable <T>的实现更值得怀疑.可能最好的做法是允许基类实现它,如果不期望任何子类需要一些其他排序,但子类不重新实现或覆盖父类实现.
| 归档时间: |
|
| 查看次数: |
4313 次 |
| 最近记录: |