私がとを持っているListA
としましょうobjectA
。
objectA
名前、年齢、rollno、ランクがあります
およびその他ListB
。objectB
objectB
名前、年齢があります
2つのリストを比較し、名前と年齢に基づいて珍しいレコードを除外するにはどうすればよいですか。
クラスのサンプルは次のとおりです。
public interface IHaveNameAndAge
{
string Name { get; set; }
int Age { get; set; }
}
public class ObjectA : IHaveNameAndAge
{
public string Name { get; set; }
public int Age { get; set; }
int RollNo { get; set; }
int Rank { get; set; }
}
public class ObjectB : IHaveNameAndAge
{
public string Name { get; set; }
public int Age { get; set; }
}
public class MyEqualityComparer : IEqualityComparer<IHaveNameAndAge>
{
public bool Equals(IHaveNameAndAge x, IHaveNameAndAge y)
{
if (ReferenceEquals(x, y))
return true;
return x.Age == y.Age && String.Equals(x.Name, y.Name, StringComparison.Ordinal);
}
public int GetHashCode(IHaveNameAndAge obj)
{
return obj.Age.GetHashCode() ^ obj.Name.GetHashCode();
}
}
テストコードは次のとおりです。
var listA = new List<ObjectA>();
listA.Add(new ObjectA() { Name = "A", Age = 20 });
listA.Add(new ObjectA() { Name = "B", Age = 25 });
var listB = new List<ObjectB>();
listB.Add(new ObjectB() { Name = "A", Age = 20 });
listB.Add(new ObjectB() { Name = "C", Age = 29 });
var myComparer = new MyEqualityComparer();
var result = listA.Intersect<IHaveNameAndAge>(listB, myComparer);
要件に応じて、この例を変更できます。
共通の基本型を持たない異なる型を比較するためのちょっとしたトリックを次に示します。IEqualityComparer<object>
次のようなものを作成します。
public class DynamicComparer : IEqualityComparer<object>
{
public bool Equals(dynamic x, dynamic y)
{
return x.Name == y.Name && x.Age == y.Age;
}
public int GetHashCode(dynamic obj)
{
return ((string)obj.Name).GetHashCode() * 31
+ ((int)obj.Age).GetHashCode();
}
}
次に、これを行うことができます:
var filtered = ListA.Intersect(ListB, new DynamicComparer())
.Cast<objectA>().ToList();
使い方。object
はすべての型に共通の基本型であるため、 はさまざまIEqualityComparer<object>
な型で正常に機能します。Name
ただし、とAge
プロパティは で定義されていないため、通常はこれらを比較することはできませんobject
。ここでの秘訣は、コンパイラーがメソッドのシグネチャーのdynamic
代わりに配置することを許可し、それらは依然としてコントラクトを満たしているということです。したがって、動的ランタイムを利用して、とタイプの両方に共通するプロパティを比較することができます。object
IEqualityComparer<object>
objectA
objectB