2016-05-18 30 views
2

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

 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

它们可能是代表同一事物的不同对象。检查你的'Equals'方法(或制作一个)。你的尝试是正确的,但是与'相同'对象比较时,比较评估'false' – Rob

回答

3

Linq。除应该能够比较权限对象的相等性。如果您有权访问权限源代码,则只需覆盖Equals和GetHashCode。当defaultPermList.Except(rolePermList).ToList()将被调用 - 它首先通过object.GetHashCode平等的所有元素比较()和thouse具有相同的hashCode wolud与的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 
    } 
} 

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

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; 
    } 
} 

差异仅仅是一个spimple类:

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

用法:

List<Variance> rt = nstanceA.DetailedCompare(InstanceB); 
相关问题