比较LINQ中的两个类-geting';不匹配';
本文关键字:-geting 不匹配 两个 LINQ 比较 | 更新日期: 2023-09-27 18:22:32
我有以下类:
public class DocumentCompare
{
public string Customer;
public string Filename;
public string Reference;
public DateTime? Date;
public override bool Equals(object obj)
{
if (obj == null)
return false;
DocumentCompare doc = obj as DocumentCompare;
if ((Object)doc == null)
return false;
return (doc.Customer == Customer) && (doc.Date == Date) && (doc.Filename == Filename) && (doc.Reference == Reference);
}
public bool Equals(DocumentCompare doc)
{
if ((object)doc == null)
return false;
return (doc.Customer == Customer) && (doc.Date == Date) && (doc.Filename == Filename) && (doc.Reference == Reference);
}
public override int GetHashCode()
{
return string.Format("{0}_{1}_{2}_{3}",Customer,Filename,Reference,(Date == null ? "" : Date.Value.ToString())).GetHashCode();
}
}
我将检索这个类的两个列表——我想做的是比较这两个列表,并得到两个列表中都不存在的列表。因此,如果一个项目存在于x列表中,但不存在于y中,我想对该列表中的项目执行一个操作。如果一个项目存在于y列表中,但不存在于x中,我想执行不同的操作。
我该怎么做?我想是在用LINQ吧!
EDIT:性能不是什么大问题-这只会运行一次
听起来你只想要Except
:
foreach (var newItem in firstList.Except(secondList))
{
...
}
题外话:
- 这不是生成哈希代码的好方法——在这里搜索其他问题
- 从
Equals(object)
委派到Equals(DocumentCompare)
以避免重复逻辑 - 可变类型不是进行相等比较的好候选者(尤其是在字典中使用值作为关键字的类型,如果更改对相等敏感的组件,将无法再次找到关键字)
- 即使确实希望它是可变的,属性也比公共字段更适合封装
- 我要么密封类型,要么检查这两个对象是否完全是同一类型,否则你可能会得到不对称的相等
这里是代码:
var elementsMissingFromFirstList = firstList.Except(secondList).ToList();
var elementsMissingInSecondList = secondList.Except(firstList).ToList();
现在,您可以对这些缺失的元素执行操作:)
您可以使用此方法来比较两个不同列表的对象。exmp:List and List x and y=DocumentCompare,
public static bool EqualsObject<T>(this T t1, T t2) where T : class
{
var p1 = t1.GetType().Fields();
var p2 = t2.GetType().Fields();
for (int j = 0; j < p1.Length; j++)
{
var x = p1[j].GetValue(t1, null);
var y = p2[j].GetValue(t2, null);
if (x == null && y == null)
continue;
if (x != null && y == null)
return false;
if (x == null)
return false;
if (!x.Equals(y))
{
return false;
}
}
return true;
}
此方法将显示这两个列表之间的差异。
public static List<T> DifferentObjects<T>(List<T> t, List<T> t2) where T : class
{
var diff = new List<T>();
if (t != null && t2 != null)
{
foreach (T t1 in t)
{
var state = false;
foreach (T t3 in t2.Where(t3 => EqualsObject(t1,t3)))
{
state = true;
}
if (!state)
{
diff.Add(t1);
}
}
}
return diff;
}
你可以这样使用代码
var t = new List<DocumentCompare>();
var t2 = new List<DocumentCompare>();
t.Add(new DocumentCompare{Customer = "x"});
t.Add(new DocumentCompare{Customer = "y"});
t.Add(new DocumentCompare{Customer = "z"});
t2.Add(new DocumentCompare { Customer = "t" });
t2.Add(new DocumentCompare { Customer = "y" });
t2.Add(new DocumentCompare { Customer = "z" });
var list = DifferentObjects(t, t2);
var list2 = DifferentObjects(t2, t);
您在类中使用了字段(Customer、FileName等),因此GetType().fields();在EqualsObject方法中使用。如果使用property,则应使用GetType().Properties();在EqualsObject方法中。