I'm having trouble getting two instances of Signature to be equal by delegating the equality check to their inner HashSet.SetEquals method, (the .Members property). I can't get a simple check to work.
SignatureMember m = new SignatureMember(typeof(int), "Test", 1);
SignatureMember b = new SignatureMember(typeof(int), "Test5", 1);
Assert.IsFalse(m == b); //Passes, as it should
Signature s = new Signature();
Signature o = new Signature();
s.Members.Add(m);
o.Members.Add(b);
Assert.IsTrue(s == o); // Fails. But using the custom comparer should mean the sets are equal.
Note the custom SignatureMemberComparer below. What am I missing?
internal sealed class Signature:IEquatable<Signature>
{
public string Name { get;internal set; }
internal HashSet<SignatureMember> Members { get; init; } = new HashSet<SignatureMember>(new SignatureMemberComparer());
public override bool Equals(object? obj)
{
if (obj == null) { return false; }
else { return Members.SetEquals(((Signature)obj).Members); }
}
public bool Equals(Signature? other)
{
if (other == null) { return false; }
else { return Members.SetEquals(other.Members); }
}
public int GetHashCode([DisallowNull] Signature obj)
{
return Members.GetHashCode();
}
}
internal class SignatureMemberComparer : IEqualityComparer<SignatureMember>
{
public bool Equals(SignatureMember? x, SignatureMember? y)
{
if(x== null & y == null) { return true; }
else if (x != null && y != null)
{
return x.Type == y.Type && x.Count == y.Count;
}
else { throw new ArgumentOutOfRangeException(); }
}
public int GetHashCode([DisallowNull] SignatureMember obj)
{
return (obj.Type, obj.Count).GetHashCode();
}
}
internal record class SignatureMember
{
public string Name { get; init; }
public Type Type { get; init; }
public int Count { get; init; }
public SignatureMember(Type type, string name, int count)
{
Name = name;
Type = type;
Count = count;
}
public override int GetHashCode()
{
return (Name, Type, Count).GetHashCode();
}
}