获取相同类型对象的两个列表之间的差异

时间:2016-05-18 14:15:29

标签: c# asp.net-mvc list

我有两个完全相同类型对象的列表。一个人的物品多于另一个。我想找到两者之间的区别,并尝试了多种方式,但似乎都返回完整列表,而不是差异是一个项目或更多。

        List<Permission> defaultPermList = defaultRole.Permissions.ToList();
        foreach (var role in roles)
        {
            List<Permission> rolePermList = role.Permissions.ToList();
            //All 3 below return the full set of defaultPermList. not the difference of the two lists
            var permissions1 = defaultPermList.RemoveAll(x => rolePermList.Contains(x));
            var permissions2 = defaultPermList.Where(x => !rolePermList.Contains(x)).ToList();
            var permissions3 = defaultPermList.Except(rolePermList).ToList();
        }

我已经查看了许多其他问题和答案,因此我尝试了不同的尝试。

2 个答案:

答案 0 :(得分:3)

Linq .Except 应该能够比较Permissions对象的相等性。如果您可以访问权限源代码,则只需覆盖Equals和GetHashCode。当 defaultPermList.Except(rolePermList).ToList()将被调用时 - 它首先通过 object.GetHashCode()和具有相同hashCode wolud的thouse比较相等的所有元素与 object.Equals()进行比较,除非我们覆盖它们。

public class Permissions
{ 

 public string Name;  // fields just for showing how to use them
 public int Rights;

 public override bool Equals(object obj)
   {
    var permission = obj as Permissions;
    if (permission != null) 
       {
          if(permission?.Name.Equals(this.Name) && permission.Rights.Equals(this.Rights)
          {
             return true;
          }
       }
       return false
    }

    public override int GetHashCode()
    {
       return Name.GetHashCode() + 3*Rights.GetHashCode(); // you might use any alghorithm you see fit
    }
 }

这应该足以使除了工作。但如果没有权限访问权限源代码 - 那么你可能应该编写自己的方法并在那里比较项目。

答案 1 :(得分:2)

如果您不喜欢linq方法,您可以自己轻松完成此操作。 基本上,您为所有类型创建一个扩展方法,并遍历每个属性并列出更改(通过反射)。

见这里:

Compare two objects and find the differences

这是没有空指针异常的更好版本:

static class extentions
{ 
    public static List<Variance> DetailedCompare<T>(this T val1, T val2)
    {
        List<Variance> variances = new List<Variance>();
        FieldInfo[] fi = val1.GetType().GetFields();
        foreach (FieldInfo f in fi)
        {
            Variance v = new Variance();
            v.Prop = f.Name;
            v.valA = f.GetValue(val1);
            v.valB = f.GetValue(val2);
            if (!Equals(v.valA, v.valB))   variances.Add(v);
        }
        return variances;
    }
}

方差只是一个简单的类:

class Variance
{
    public string Prop { get; set; }
    public object valA { get; set; }
    public object valB { get; set; }
}

用法:

List<Variance> rt = nstanceA.DetailedCompare(InstanceB);