2016-05-18 4 views
2

全く同じタイプのオブジェクトの2つのリストがあります。 1つは他のものより多くの項目を持っています。私は2つの違いを見つけて、複数の方法を試みましたが、すべてが完全なリストを返すように見えますが、違いは1つ以上のアイテムではありません。同じ種類のオブジェクトの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.Exceptは、Permissionsオブジェクトの等価性を比較できる必要があります。アクセス権ソースコードにアクセスできる場合は、EqualsとGetHashCodeをオーバーライドします。ときdefaultPermList.Except(rolePermList).ToList()が呼び出されます - それは最初Object.GetHashCodeをによって平等にすべての要素を比較はObject.equalsと比較wolud同じハッシュコードを持っている()とthouse()私たちがそれらを上書きしない限り。仕事を除いて作られたのに十分でなければならない

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

はありませんnullポインタ例外とのより良いバージョンです:

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); 
関連する問題