C#比较两个未知types的对象(包括引用和值types)
是否有可能在C#中使用它们的types比较器比较两个未知types的对象(包括引用types和值types)是否存在?
我们的目标是编写一个具有如下签名的函数:
public bool Compare(object a, object b) { // compare logic goes here }
哪会回来
Compare(100d, 100d) == true Compare(100f, 100f) == true Compare("hello", "hello") == true Compare(null, null) == true Compare(100d, 101d) == false Compare(100f, null) == false // Use type comparators where possible, ie: Compare(new DateTime(2010, 12, 01), new DateTime(2010, 12, 01)) == true Compare(new DateTime(2010, 12, 01), new DateTime(2010, 12, 02)) == false Compare(new DateTime(2010, 12, 01), null) == false
有没有一个通用的方法来解决这个问题,将适用于任何types的对象?
你可以使用静态的object.Equals(object x, object y)
方法,而不用费神写你的方法。 这将适当地处理空值,并委托到与x
或y
有关的object.Equals(object)
的实现…它应该无关紧要,因为Equals
意味着是对称的。
请注意,这不会为任何types使用==运算符 – 操作符不能被重载,只会被重载(这意味着它们是在编译时select的,而不是在执行时select的 。在大多数情况下, Equals
应该做你想做的在某些情况下,即使Equals
被覆盖,==也不会被重载…但是我从来不知道任何types的对象都是真的。
请注意,使用这种方法将框中的任何值types…
编辑:删除部分有关重新实施 – 很差 – EqualityComparer<T>.Default
。 请参阅Marc的更多答案。 当然,如果你不能使用genericstypes,这将无济于事。
最后一点:我不会打电话给你的方法Compare
。 这个名字通常与sorting值相关,而不是比较它们是否相等。
一个合理的select是使用generics,即
public bool Compare<T>(T a, T b) {...}
您不需要在您的代码中指定T
,因为编译器通常能够将其解决(即您现有的样本将按原样工作)
为了执行:
bool equal = EqualityComparer<T>.Default.Equals(x, y);
(对于通用typesT
)
但实际上我会避免Compare
,因为这是其他地方使用意味着<
/ ==
/ >
– 所以我可能有:
public static bool Equals<T>(T a, T b) { return EqualityComparer<T>.Default.Equals(a, b); }
这个:
- 当T是一个结构体时避免装箱
- 正确处理null /
Nullable<T>
- 支持
IEquatable<T>
- 或回落到正常的
Equals
它不使用==
运算符,但MiscUtil有一个Operator
类, 将通过
bool equal = Operator.Equal<T>(x,y);
(注意,如果T
没有==
运算符,则后者将会失败,但考虑到它,可以使用EqualityComparer<T>.Default.Equals
作为后备;它不会)
为了完整性,请注意Comparer<T>.Default.Compare(x,y)
处理比较操作。
如何object.equals(x, y)
? 这也将接受空值。
关于什么
if (a == null && b == null) return true; if (a == null && b != null) return false; return (a.equals(b));
?
我不能100%确定这是否适用于所有情况,但请试一试
public bool比较(对象a,对象b) { (b); }