我有场景要检查
1) 如果 empDb
中的任何属性 (EmployeeObject) 出现在 empXml
中,则返回 true
。否则返回 false
public class EmployeeObject
{
public Int32 Id { get; set; }
public string Title { get; set; }
public string Desc { get; set; }
.....
}
IList<EmployeeObject> empDb = PopulateFromDb(); //calling ado.net
IList<EmployeeObject> empXml = PopulateFromXml(); //deserializing xml
让我直截了本地说,我正在尝试确定列表 empXml
是否是列表 empDb
的子集?
到目前为止已经尝试过;但即使我已经检查了两个列表中的数据,它也返回 false,它应该返回 true,除非我在我的表达式中做错了什么。
//at least one MATCH
empDb.Any(a => empXml.Contains(a));
或
//at least one EXACT match
empDb.Any(x => empXml.Contains(y => x.Equals(y)));
最佳答案
如果您没有在 EmployeeObject
类中实现 Equals
和 GetHashCode
,那么员工将通过引用进行比较。你肯定会在这里有不同的实例,因为第一个列表是在你从数据库中读取数据时创建的,而第二个列表是在你反序列化 xml 时创建的。因此,即使是在所有领域具有相同值(value)观的员工也会被认为是不同的。
如果您只想通过员工 ID 检查匹配项,那么您可以将序列投影到 ID,然后使用 Intersect检查匹配是否存在
// at least one employee with equal Id
empDb.Select(e => e.Id).Intersect(empXml.Select(e => e.Id)).Any()
如果您想按员工字段的值而不是他们的引用来比较员工,您有多种选择。如果您不能或不想更改 EmployeeObject 类的实现并覆盖其 Equals 和 GetHashCode 方法,那么您可以为员工创建自定义的比较器:
public class EmployeeComparer : IEqualityComparer<EmployeeObject>
{
public bool Equals(EmployeeObject x, EmployeeObject y)
{
return x.Id == y.Id
&& x.Title == y.Title
&& x.Desc == y.Desc;
}
public int GetHashCode(EmployeeObject obj)
{
int code = 19;
code = code * 23 + obj.Id.GetHashCode();
code = code * 23 + obj.Title.GetHashCode();
code = code * 23 + obj.Desc.GetHashCode();
return code;
}
}
然后你可以使用这个比较器:
empDb.Intersect(empXml, new EmployeeComparer()).Any()
或者您可以将您的员工转换到匿名对象(默认实现了 Equals 和 GetHashCode):
empDb.Select(e => new { e.Id, e.Title, e.Desc })
.Intersect(empXml.Select(e => new { e.Id, e.Title, e.Desc })).Any()
或者覆盖这些方法:
public class EmployeeObject
{
public Int32 Id { get; set; }
public string Title { get; set; }
public string Desc { get; set; }
public override int GetHashCode()
{
int code = 19;
code = code * 23 + Id.GetHashCode();
code = code * 23 + Title.GetHashCode();
code = code * 23 + Desc.GetHashCode();
return code;
}
public override bool Equals(object obj)
{
EmployeeObject other = obj as EmployeeObject;
if (other == null)
return false;
if (ReferenceEquals(this, other))
return true;
return Id == other.Id &&
Title == other.Title && Desc == other.Desc;
}
}
您的代码将起作用。或者您可以使用相交:
empDb.Intersect(empXml).Any()
关于c# - 比较两个自定义 LIST 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21556338/