C#/ Linq:检测到两个列表类型之间的差异

时间:2015-07-12 19:10:18

标签: c# linq

我想检测一些数据是否使用Linq更改。

我有这堂课:

public class MyData 
{
    public string Nombre {get; set;}
    public string Tipo {get; set;}
    public int Longitud {get; set;}
}

我有一个类型的列表,我可以更改数据,另一个是更改之前的副本。

键入结构:

List<MyData> data = new List<MyData>();

 // suppose I load data here in data variable.

List<MyData> mycopy = data;

var mydatatochange = data.Where(...).ToList();

mydatatochange

...or...

MyData info = new MyData();
info.Nombre = "aaa";
info.Tipo = "something";

data.Add(info);

现在我想看看datamycopy之间是否存在某种差异。

我正在尝试使用Linq。

2 个答案:

答案 0 :(得分:2)

以下是检测已添加,已删除和已更改项目的代码:

List<MyData> lst = new List<MyData>();

lst.Add(new MyData()
        {
            Longitud = 1,
            Tipo = "123",
            Nombre = "n1"
        });


        lst.Add(new MyData()
        {
            Longitud = 1,
            Tipo = "456",
            Nombre = "n1"
        });

        var cloned = lst.ToList();
        Dictionary<MyData, Tuple<string, string, int>> originalValues = new Dictionary<MyData, Tuple<string, string, int>>();

        foreach (var item in cloned)
            originalValues[item] = new Tuple<string, string, int>(item.Nombre, item.Tipo, item.Longitud);


        cloned.Remove(lst[0]);
        cloned.Add(new MyData()
        {
            Longitud = 2,
            Nombre = "aaaaaa",
            Tipo = "gggg"
        });

        var added = (from p in cloned

                     join orig in lst
                         on p equals orig into left
                     from orig in left.DefaultIfEmpty()
                     where orig == null
                     select p).ToList();

        var deleted = (from orig in lst
                       join c in cloned
                           on orig equals c into left
                       from c in left.DefaultIfEmpty()
                       where c == null
                       select orig).ToList ();

        var changed = (from orig in lst
                       join c in cloned
                           on orig equals c
                       where originalValues[orig].Item1 != orig.Nombre ||
                           originalValues[orig].Item2 != orig.Tipo ||
                           originalValues[orig].Item3 != orig.Longitud
                       select orig
                            ).ToList();

答案 1 :(得分:1)

为了检查一个对象是否等于另一个,你可以使用object.Equals(otherObject),但是......

在您的示例中,您执行:List<MyData> mycopy = data;,它不会被复制,但它会创建像对象一样的指针,如果您更改数据对象,它也会更改。所以为了让它发挥作用:

1)使用以下代码编辑MyData类:

public class MyData
{
    public MyData(string nombre, string tipo, int longitud)
    {
        Nombre = nombre;
        Tipo = tipo;
        Longitud = longitud;
    }

    public MyData(MyData itemToCopy)
    {
        Nombre = itemToCopy.Nombre;
        Tipo = itemToCopy.Tipo;
        Longitud = itemToCopy.Longitud;
    }

    public string Nombre { get; set; }
    public string Tipo { get; set; }
    public int Longitud { get; set; }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
        {
            return false;
        }

        if (ReferenceEquals(this, obj))
        {
            return true;
        }

        if (obj.GetType() != this.GetType())
        {
            return false;
        }

        return Equals((MyData)obj);
    }

    protected bool Equals(MyData other)
    {
        return string.Equals(this.Nombre, other.Nombre) && string.Equals(this.Tipo, other.Tipo) && this.Longitud == other.Longitud;
    }

    public override int GetHashCode()
    {
        unchecked
        {
            var hashCode = (this.Nombre != null ? this.Nombre.GetHashCode() : 0);
            hashCode = (hashCode * 397) ^ (this.Tipo != null ? Tipo.GetHashCode() : 0);
            hashCode = (hashCode * 397) ^ this.Longitud;
            return hashCode;
        }
    }
}

2)创建列表克隆:

List<MyData> mycopy = new List<MyData>();

data.ForEach((item)=>
    {
        mycopy.Add(new MyData(item));
    });

3)使用此代码,您可以检查它是否等于:

var isEqual = data.Count == copy.Count;
if (isEqual)
{
    isEqual = !data.Where((t, i) => !t.Equals(copy[i])).Any();
}