C#比较两个未知类型的对象(包括引用和值类型)

时间:2010-12-02 07:22:08

标签: c# .net

C#中是否可以使用类型比较器比较两个未知类型的对象(包括引用和值类型)?

目标是编写一个具有如下签名的函数:

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, i.e.:
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

是否有解决此问题的通用方法适用于任何类型的对象?

5 个答案:

答案 0 :(得分:61)

您可以使用静态object.Equals(object x, object y)方法,而不必费心编写方法。这将适当地处理空值,并委托给与object.Equals(object)x相关联的y实现... 不应该 {1}}意味着对称。

请注意,此使用任何类型的==运算符 - 运算符不能被重写,只能重载(这意味着它们是在编译时选择的,而不是执行时间。在大多数情况下Equals应该做你想要的。在某些情况下,即使Equals被覆盖,==也可能不会超载。但是我从来不知道在我使用过的任何类型中都是如此。

请注意,使用此方法将任何值类型...

编辑:删除了有效重新实现的部分 - 很差 - Equals。请参阅Marc的答案。如果你不能使用通用类型,这对你没有帮助。

最后一点:我不会调用您的方法EqualityComparer<T>.Default。该名称通常与排序值相关联,而不是将它们进行相等性比较。

答案 1 :(得分:20)

合理的选择是使用泛型,即

public bool Compare<T>(T a, T b) {...}

您不需要在代码中指定T,因为编译器通常能够找出它(即您现有的样本将“按原样”工作)

执行:

bool equal = EqualityComparer<T>.Default.Equals(x, y);

(对于通用类型T

实际上我会避免使用Compare这个词,因为在其他地方使用的是< / == / > - 所以我可能有:

public static bool Equals<T>(T a, T b) {
    return EqualityComparer<T>.Default.Equals(a, b);
}

此:

  • 当T是结构时避免装箱
  • 正确处理空值/ Nullable<T>
  • 支持IEquatable<T>
  • 或回归常规Equals

使用==运算符,但MiscUtil有<{1}}类,通过

Operator

(请注意,如果bool equal = Operator.Equal<T>(x,y); 没有T运算符,后者将会失败,尽管考虑到它,它可以使用==作为后备;它只是没有)


为完整起见,请注意EqualityComparer<T>.Default.Equals处理比较操作。

答案 2 :(得分:5)

object.equals(x, y)怎么样?这也将接受空值。

答案 3 :(得分:0)

怎么样?
if (a == null && b == null) return true;
if (a == null && b != null) return false;
return (a.equals(b));

答案 4 :(得分:-2)

我不是百分百确定这是否适用于所有情况,但尝试一下

public bool Compare(object a, object b)
{
    return a.Equals(b);
}