我想比较两个对象,例如:
DirectoryInfo di1 = new DirectoryInfo("C:\\");
DirectoryInfo di2 = new DirectoryInfo("C:\\");
好的,是的,我知道我们这里有不同的引用,这个类没有实现IComparable,甚至GetHashCode也会返回不同的结果。
但他们是一样的! (逻辑:))
我知道我可以使用反射来比较类之间的每个字段和属性,但它太慢了。
我也可以使用序列化;序列化每个对象并比较二进制数据,但这更慢!
还有其他想法吗?
答案 0 :(得分:5)
我建议创建IEqualityComparer<DirectoryInfo>
的实现并在其中封装相等性检查代码。以下是有关IEqualityComparer<T>
的文档的链接:
答案 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)
你真的想要比较什么?
一旦你弄清楚了,你就可以在hashcode或IComparable,IComparer,Equals,Equatable等中编写你的比较。
我会亲自检查一个Windows路径,使用字符串的哈希码。你不能拥有“C:\ blah”和“C:\ Blah”,但你可以在基于Unix的操作系统中使用(或者C:\将是/或〜/)。
因此,在我看来,检查两条路径很好。就像Michael Meadows写的一样。