比较具有相同数据的两个对象

时间:2009-03-24 19:24:51

标签: c# reflection serialization comparison

我想比较两个对象,例如:

 DirectoryInfo di1 = new DirectoryInfo("C:\\");
 DirectoryInfo di2 = new DirectoryInfo("C:\\");

好的,是的,我知道我们这里有不同的引用,这个类没有实现IComparable,甚至GetHashCode也会返回不同的结果。

但他们是一样的! (逻辑:))

我知道我可以使用反射来比较类之间的每个字段和属性,但它太慢了。

我也可以使用序列化;序列化每个对象并比较二进制数据,但这更慢!

还有其他想法吗?

8 个答案:

答案 0 :(得分:5)

我建议创建IEqualityComparer<DirectoryInfo>的实现并在其中封装相等性检查代码。以下是有关IEqualityComparer<T>的文档的链接:

http://msdn.microsoft.com/en-us/library/ms132151.aspx

答案 1 :(得分:4)

di1.FullPath == di2.FullPath出了什么问题?

如果完整路径相同,则可以推导出它们是同一目录,即使实例属性不同也是如此。在大多数情况下,进行更深入的比较似乎毫无意义。

答案 2 :(得分:2)

编写一个进行比较的函数。例如,给定此类型:

class Foo
{
    public int Bar;
}

写一个这样的函数:

static Boolean areEqual(Foo first, Foo second)
{
    return first.Bar == second.Bar;
}

修改

以下是如何将此作为扩展方法:

static class Extensions
{
    public static Boolean Equals(this Foo source, Foo foo)
    {
        return first.Bar == second.Bar;
    }
}

这将允许您这样做:

Foo first = new Foo();
Foo second = new Foo();
Boolean areEqual = first.Equals(second);

答案 3 :(得分:1)

是的,理想情况下,GetHashCode()应该为相同的数据返回相同的值,但.NET框架中有很多类依赖于为不同引用具有不同值的默认行为。

话虽如此,GetHashCode()返回相同的值不应该用作任何类的相等指示符。此函数旨在帮助哈希表(和类似)结构的内存存储,其中可用于近似相等或近似值函数。

在您的情况下,您唯一真正的选择是自己编写。如果这是用于像IDictionary这样的东西,那么你需要创建一个实现IEqualityComparer接口的具体类。

简而言之,没有一种通用的,一刀切的方法来确定引用类型上的数据相等性,因为各种类型的含义可以(并且将会)发生变化。

答案 4 :(得分:0)

这是IEquatable界面的存在理由,它是旧的object.Equals()方法的强类型版本。 (或者也许IComparable,但你提到它没有实现它。)

如果您使用“平等”的合理含义派生自己的对象并不意味着“相同的引用”,那么您应该实现IEquatable和/或覆盖object.Equals()。鉴于您正在使用没有这个的对象,您将必须创建一个函数来以您认为合适的方式比较它们的相关属性。

答案 5 :(得分:0)

您要比较的DirectoryInfo路径吗?使用.ToString()并以字符串格式比较路径。

答案 6 :(得分:0)

我认为反思是唯一可行的。您可以使用代码生成甚至使用LINQ表达式来优化它。

答案 7 :(得分:0)

你真的想要比较什么?

  1. 路径
  2. 每个目录中的文件数及其路径
  3. 所有子文件路径
  4. 所有子文件及其所有属性(即大量比较)
  5. 所有子目录
  6. 所有子文件及其所有属性(同上至3)
  7. 以上所有
  8. 一旦你弄清楚了,你就可以在hashcode或IComparable,IComparer,Equals,Equatable等中编写你的比较。

    我会亲自检查一个Windows路径,使用字符串的哈希码。你不能拥有“C:\ blah”和“C:\ Blah”,但你可以在基于Unix的操作系统中使用(或者C:\将是/或〜/)。

    因此,在我看来,检查两条路径很好。就像Michael Meadows写的一样。