-1

编辑:

我想要做的是找到是否db.Id等于xml.Iddb.SubTitle等于xml.SubTitle......等等......我的所有道具

我也试过

bool result = db.SequenceEqual(xml)它一直返回false。

结束编辑

在最终寻求帮助之前,我确实进行了搜索,但我不确定解决我的问题的最佳方法是什么。

我有两个 IList 对象,它们都具有完全相同的属性,但数据可能不同。一个对象从 db 填充,另一个对象从 xml 读取以比较两个源是否同步。

这是我的对象的样子:

public class EmployeeObject
{
    public Int32 Id { get; set; }
    public string SubTitle { get; set; }
    public string Desc { get; set; }
    public bool Active { get; set; }
    public string ActiveDateTime { get; set; }
}

这是我尝试过的:

    IList<EmployeeObject> db = Db.EmployeeRepository.PopulateFromDb();
    IList<EmployeeObject> xml = Xml.EmployeeRepository.PopulateFromXml();

//到目前为止,这两个对象都填充了数据,非常好......

是时候比较一下了:

我尝试过这样的事情:

   if ((object)xml == null || ((object)db) == null)
       return Object.Equals(xml, db);

   return xml.Equals(db); // returning false all the time

我已经检查了两个对象具有完全相同的数据,但仍然返回false

4

6 回答 6

7

您使用的Equals方法将确定两个引用是否引用相同的列表,而不是内容是否相同。您可以使用SequenceEqual实际验证两个序列是否具有相同顺序的相同项目。

接下来,您将遇到这样的问题:列表中的每个项目都将被比较以查看它们是否引用相同的对象,而不是包含相同的字段值或相同的 ID 值,这似乎是您想要的. 一种选择是自定义比较器,但另一种选择是提取有问题的“身份”对象:

bool areEqual = db.Select(item => item.id)
    .SequenceEqual(xml.Select(item => item.id));
于 2013-10-23T22:32:46.327 回答
2

IList没有Equals方法。您所调用的是标准Object equals,它检查两个变量是否指向同一个对象。

如果要检查列表在语义上是否等效,则需要检查列表中的每个对象是否等效。如果EmployeeObject该类具有适当的Equals方法,则可以使用SequenceEquals来比较列表。

于 2013-10-23T22:26:25.857 回答
2

你应该像这样在你的类中覆盖Equals和:GetHashCode

public class EmployeeObject {
  public Int32 Id { get; set; }
  public string SubTitle { get; set; }
  public string Desc { get; set; }
  public bool Active { get; set; }
  public string ActiveDateTime { get; set; }
  public override bool Equals(object o){
     EmployeeObject e = o as EmployeeObject;
     if(e == null) return false;
     return Id == e.Id && SubTitle == e.SubTitle && Desc == e.Desc 
            && Active == e.Active && ActiveDateTime == e.ActiveDateTime; 
  }
  public override int GetHashCode(){
     return Id.GetHashCode() ^ SubTitle.GetHashCode() ^ Desc.GetHashCode()
            ^ Active.GetHashCode() ^ ActiveDateTime.GetHashCode();             
  }
}

然后使用SequenceEqual方法:

return db.OrderBy(e=>e.Id).SequenceEqual(xml.OrderBy(e=>e.Id));
于 2013-10-23T22:30:21.413 回答
1

您可以实现IEqualityComparer并使用采用IEqualityComparer的 SequenceEquals 的重载。下面是来自 msdn 的 IEqualityComparer 的示例代码:

class BoxEqualityComparer : IEqualityComparer<Box>
{
    public bool Equals(Box b1, Box b2)
    {
        if (b1.Height == b2.Height && b1.Length == b2.Length && b1.Width == b2.Width)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public int GetHashCode(Box bx)
    {
        int hCode = bx.Height ^ bx.Length ^ bx.Width;
        return hCode.GetHashCode();
    }
}

然后,您可以像这样使用 SequenceEquals:

if (db.SequnceEquals(xml), new MyEqualityComparer())
    { /* Logic here */ }

请注意,仅当项目也以列表中的相同顺序排序时,这才会返回 true。如果合适,您可以像这样预购商品:

if (db.OrderBy(item => item.id).SequnceEquals(xml.OrderBy(item => item.id)), new MyEqualityComparer())
    { /* Logic here */ }
于 2013-10-23T22:34:17.910 回答
0

显然,如果您正在比较两个不同的列表,return xml.Equals(db);则总是会返回。false

唯一有意义的方法是让您更具体地了解这两个列表相等的含义。也就是说,您需要遍历两个列表中的元素并确保两个列表都包含相同的项目。即使这是模棱两可的,但假设您的元素提供了适当的覆盖Equals()GetHashCode()然后您可以继续实现实际的列表比较。

通常,比较两个不包含重复的列表的最有效方法是使用由其中一个列表的元素构造的哈希集,然后遍历第二个列表的元素,测试是否在哈希中找到每个元素放。

如果列表包含重复项,最好的办法是对它们进行排序,然后串联遍历列表,确保每个点的元素都匹配。

于 2013-10-23T22:26:48.133 回答
0

如果SequenceEqual您可以实际比较EmployeeObject. 您可能必须Equals打开EmployeeObject

public override bool Equals(object o)
{
  EmployeeObject obj = o as EmployeeObject;
  if(obj == null) return false;

  // Return true if all the properties match
  return (Id == obj.Id &&
          SubTitle == obj.SubTitle &&
          Desc == obj.Desc &&
          Active == obj.Active &&
          ActiveDateTime == obj.ActiveDateTime);
}

然后你可以这样做:

var same = db.SequenceEqual(xml);

您还可以传入一个实现IEqualityComparer指示SequenceEqual如何比较每个实例的类:

var same = db.SequenceEqual(xml, someComparer);

另一种快速的方法,虽然不是那么快,但是建立两个你想要比较的值的枚举,可能是id你的情况下的属性:

var ids1 = db.Select(i => i.Id); // List of all Ids in db
var ids2 = xml.Select(i => i.Id); // List of all Ids in xml
var same = ids1.SequenceEqual(ids2); // Both lists are the same
于 2013-10-23T22:35:44.493 回答