Je voudrais comparer deux listes d'objets imbriqués. Si les objets parents Id
différer et/ou l'un des enfants Id
o Baz
les propriétés diffèrent, je veux les considérer comme modifiées.
J'ai implémenté ma propre version de Equals
y GetHashCode
ci-dessous, mais malgré l'utilisation de mon propre comparateur d'égalité, Except()
donne toujours un résultat, alors que je m'attends à ce que les objets soient égaux.
var foo1 = new Foo
{
Id = 1,
Bars = new List<Bar>
{
new Bar
{
Id = 1,
Baz = 1.5
},
new Bar
{
Id = 1,
Baz = 1.5
}
}
};
var foo2 = new Foo
{
Id = 1,
Bars = new List<Bar>
{
new Bar
{
Id = 1,
Baz = 1.5
},
new Bar
{
Id = 1,
Baz = 1.5
}
}
};
var diff = new[] { foo1 }.Except(new[] { foo2 });
public class Foo
{
private sealed class IdBarsEqualityComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo x, Foo y)
{
if (ReferenceEquals(x, y)) return true;
if (ReferenceEquals(x, null)) return false;
if (ReferenceEquals(y, null)) return false;
if (x.GetType() != y.GetType()) return false;
return x.Id == y.Id && Equals(x.Bars, y.Bars);
}
public int GetHashCode(Foo obj)
{
unchecked
{
return (obj.Id * 397) ^ (obj.Bars != null ? obj.Bars.GetHashCode() : 0);
}
}
}
public static IEqualityComparer<Foo> IdBarsComparer { get; } = new IdBarsEqualityComparer();
public int Id { get; set; }
public List<Bar> Bars { get; set; }
}
public class Bar
{
protected bool Equals(Bar other)
{
return Id == other.Id && Baz.Equals(other.Baz);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((Bar) obj);
}
public override int GetHashCode()
{
unchecked
{
return (Id * 397) ^ Baz.GetHashCode();
}
}
public int Id { get; set; }
public double Baz { get; set; }
}