Linq语法比较两个列表

时间:2015-07-13 07:45:14

标签: c# linq

我有两个自定义类型对象列表

List<Obj> list1;
List<Obj> list2;

class Obj
{
  public List<X> xlist;
  public List<Y> Ylist;
  public bool mybool;

}

class X
{
   int x;
   float y;

}


class Y
{
   sting str;
   bool  y;

}

我想比较list1和list2中的每个成员具有相等的值。是否可以在LINQ中执行此操作。

2 个答案:

答案 0 :(得分:1)

您必须有意义地覆盖EqualsGetHashCode。您还可以实施IEquatable<Obj>或对IEqualityComparer<Obj>SequenceEqual等LINQ方法使用自定义Except。例如:

public class Obj:  IEquatable<Obj>
{
    public List<X> xlist;
    public List<Y> Ylist;
    public bool mybool;


    public bool Equals(Obj other)
    {
        if (other == null) return false;
        if(object.ReferenceEquals(this, other)) return true;
        if (mybool != other.mybool) return false;
        return xlist.SequenceEqual(other.xlist) && Ylist.SequenceEqual(other.Ylist);
    }

    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = mybool ? 13 : 19;
            foreach (X x in xlist)
            {
                hash = hash * 31 + x.GetHashCode();
            }
            foreach (Y y in Ylist)
            {
                hash = hash * 31 + y.GetHashCode();
            }
            return hash;
        }
    }
}

public class X: IEquatable<X>
{
    public int x;
    public float y;

    public bool Equals(X other)
    {
        if (other == null) return false;
        if (object.ReferenceEquals(this, other)) return true;
        return x == other.x && y == other.y;

    }

    public override bool Equals(object obj)
    {
        var other = obj as X;
        if (other == null) return false;
        return this.Equals(other);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = 19;
            hash = hash * 31 + x;
            hash = hash * 31 + (int)y;
            return hash;
        }
    }
}


public class Y : IEquatable<Y>
{
    public string str;
    public bool y;

    public bool Equals(Y other)
    {
        if (other == null) return false;
        if (object.ReferenceEquals(this, other)) return true;
        return str == other.str && y == other.y;

    }

    public override bool Equals(object obj)
    {
        var other = obj as Y;
        if (other == null) return false;
        return this.Equals(other);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = 19;
            hash = hash * 31 + (str == null ? 0 : str.GetHashCode());
            hash = hash * 31 + (y ? 1 : 0);
            return hash;
        }
    }
}

现在,您可以将SequenceEqual用于List<Obj>

bool sameItemsSameOrder = list1.SequenceEqual(list2);  // finally you got your one-liner

答案 1 :(得分:0)

有扩展方法SequenceEqual。 &#34;通过使用类型的默认相等比较器来比较元素,确定两个序列是否相等。&#34;与你自己的平等比较器重载。

var areEqual = list1.SequenceEqual(list2);

默认情况下,它会对列表中的对象调用Equals方法,因此请确保它符合您的需要或传递您自己的相等比较器。

Linq是一种查询语法。你需要Linq到例如在一个列表中查找不在另一个列表中的项目。使用SequenceEqual比较序列不是查询,恕我直言不是Linq。但是,这有关系吗?