我有两个相同类型的复杂对象。我想比较两个对象,以确定它们是否具有完全相同的值。这样做的有效方法是什么?
下面给出的样本类结构:
class Package
{
public List<GroupList> groupList;
}
class GroupList
{
public List<Feature> featurelist;
}
class Feature
{
public int qty;
}
答案 0 :(得分:5)
好的,所以你想要深度无序的结构比较。 “无序”部分很棘手,事实上它强烈暗示你的类设计不正确:List<T>
本身是有序的,所以也许你宁愿在那里使用HashSet<T>
(如果你不希望有任何重复)。这样做会使比较更容易实现,并且更快(虽然插入会更慢):
class Package
{
public HashSet<GroupList> groupList;
public override bool Equals(object o)
{
Package p = o as Package;
if (p == null) return false;
return groupList.SetEquals(p.groupList);
}
public override int GetHashCode()
{
return groupList.Aggregate(0, (hash, g) => hash ^ g.GetHashCode());
}
}
class GroupList
{
public HashSet<Feature> featureList;
public override bool Equals(object o)
{
GroupList g = o as GroupList;
if (g == null) return false;
return featureList.SetEquals(g.featureList);
}
public override int GetHashCode()
{
return featureList.Aggregate(0, (hash, f) => hash ^ f.GetHashCode());
}
}
class Feature
{
public int qty;
public override bool Equals(object o)
{
Feature f = o as Feature;
if (f == null) return false;
return qty == f.qty;
}
public override int GetHashCode()
{
return qty.GetHashCode();
}
}
如果你想继续使用List<T>
,你需要使用LINQ集操作 - 但请注意,这些操作要慢得多:
class Package
{
public List<GroupList> groupList;
public override bool Equals(object o)
{
Package p = o as Package;
if (p == null) return false;
return !groupList.Except(p.groupList).Any();
}
}
class GroupList
{
public List<Feature> featureList;
public override bool Equals(object o)
{
GroupList g = o as GroupList;
if (g == null) return false;
return !featureList.Except(f.featureList).Any();
}
}
答案 1 :(得分:2)
对于复杂对象,我会考虑运算符重载。
在重载运算符上,我将定义我的条件是否相等。
http://msdn.microsoft.com/en-us/library/aa288467%28VS.71%29.aspx
答案 2 :(得分:2)
我们总是最终在类上编写一个方法,通过一切并比较它。您可以将其实现为IComparable,或覆盖Equals。
答案 3 :(得分:2)
正如评论所说,取决于你想要衡量的“准确”程度。
您可以只覆盖相等并实现GetHashCode方法,但这并不能保证它们是完全匹配。但是会确保它们“极有可能”完全匹配。
接下来你可以做的是遍历类中的每个属性/字段并比较这些哈希值。这将“非常可能”完全匹配。
要真正获得完全匹配,您必须在递归循环中比较每个字段和成员...不推荐。
答案 4 :(得分:1)
如果我是你,我会在两种类型上实现IComparable接口:
http://msdn.microsoft.com/en-us/library/system.icomparable.aspx
从那里你可以使用.CompareTo,并在你的情况下实现所需的精确比较。这是.NET中的一般最佳实践,我认为适用于您的情况。
答案 5 :(得分:1)
取决于你想要做什么比较。像其他人一样指出IComparer是一个不错的选择。如果你打算使用lambdas和LINQ,我会使用IEqualityComparer
http://msdn.microsoft.com/en-us/library/system.collections.iequalitycomparer.aspx
答案 6 :(得分:1)
一般情况下,无论是否重载等于,都需要一种检查二者的方法,或者使用IComparer。
你问过如何最有效地做到这一点,这里有一些提示:
因此,一般来说,首先进行最快的比较以尝试返回false。
答案 7 :(得分:0)
使用反射,这是一种稍微简化的方法。您可能需要为特定比较添加其他数据类型检查或循环列表等,但这应该可以帮助您入门。
void Mymethod(){
Class1 class1 = new Class1();
//define properties for class1
Class1 class2 = new Class1();
//define properties for class2
PropertyInfo[] properties = class1.GetType().GetProperties();
bool bClassesEqual = true;
foreach (PropertyInfo property in properties)
{
Console.WriteLine(property.Name.ToString());
if (property.GetValue(class1, null) != property.GetValue(class2, null))
{
bClassesEqual = false;
break;
}
}
}