【问题标题】:Get the difference between two lists of the same type of object [duplicate]获取相同类型对象的两个列表之间的差异[重复]
【发布时间】:2016-09-15 02:21:17
【问题描述】:

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

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

我查看了许多其他问题和答案,因此我进行了所有不同的尝试。

【问题讨论】:

  • 它们可能是代表同一事物的不同对象。检查您的 Equals 方法(或制作一个)。您的尝试是正确的,但与“相同”对象进行比较时,比较正在评估 false

标签: c# asp.net-mvc list


【解决方案1】:

Linq .Except 应该能够比较 Permissions 对象的相等性。如果您有权访问 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
    }
 }

这应该足以让除外工作。但是,如果无法访问权限源代码 - 那么您可能应该编写自己的方法并在那里比较项目。

【讨论】:

    【解决方案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;
        }
    }
    

    Variance 只是一个简单的类:

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

    用法:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-28
      • 2013-04-12
      • 2013-05-02
      • 2010-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多