免責事項:BaseCode
このソリューションは、異なる/同じ場所で同じことを具体的に処理しません。あなたの要件では、これについて何も言及していません。
IEqualityComparer<T>
ルート
ここで重要な部分は、 と の両方の実装IEqualityComparer<T>
です。Person
Location
class Program
{
static void Main(string[] args)
{
var p1 = new Person {Name ="John", BaseCode="AA12", Locations = new List<Location>
{
new Location { Name = "India" },
new Location { Name = "USA" }
}};
var p2 = new Person {Name ="John", BaseCode="AA13", Locations = new List<Location>
{
new Location { Name = "India" },
new Location { Name = "USA" }
}};
var p3 = new Person {Name ="John", BaseCode="AA14", Locations = new List<Location>
{
new Location { Name = "India" },
new Location { Name = "UK" }
}};
var persons = new List<Person> { p1, p2, p3 };
// Will not return p2.
var distinctPersons = persons.Distinct(new PersonComparer()).ToList();
Console.ReadLine();
}
}
public class PersonComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
if (x == null || y == null)
return false;
bool samePerson = x.Name == y.Name;
bool sameLocations = !x.Locations
.Except(y.Locations, new LocationComparer())
.Any();
return samePerson && sameLocations;
}
public int GetHashCode(Person obj)
{
return obj.Name.GetHashCode();
}
}
public class LocationComparer : IEqualityComparer<Location>
{
public bool Equals(Location x, Location y)
{
if (x == null || y == null)
return false;
return x.Name == y.Name;
}
public int GetHashCode(Location obj)
{
return obj.Name.GetHashCode();
}
}
は、 を提供PersonComparer
する linqExcept
拡張機能を使用してLocationComparer
、2 つの場所のリスト間の違いのリストを生成します。
次にPersonComparer
、linqDistinct
メソッドにフィードします。
IEquatable<T>
ルート
BaseCode
「一致」するために異なるカウントで作業する必要がある場合GetHashCode
、値を区別する機会が与えられないため、このルートは機能しないと思います.
別の解決策はIEquatable<T>
、クラス自体に実装し、さらにオーバーライドして、GetHashCode
この実装を尊重することです。Distinct
Except
public class Person : IEquatable<Person>
{
public string Name { get; set; }
public string BaseCode { get; set; }
public List<Location> Locations { get; set; }
public bool Equals(Person other)
{
if (other == null)
return false;
bool samePerson = Name == other.Name;
// This is simpler because of IEquatable<Location>
bool sameLocations = !Locations.Except(other.Locations).Any();
return samePerson && sameLocations;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
public class Location : IEquatable<Location>
{
public string Name { get; set; }
public bool Equals(Location other)
{
if (other == null)
return false;
return Name == other.Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
これにより、呼び出しがより簡単になります。
var distinctPersons = persons.Distinct().ToList();