Reputation: 710
Given the following,
record Foo(int Id)
{
public virtual bool Equals(Foo? foo)
{
Console.WriteLine($"foo {(foo is null ? "IS" : "is NOT")} null");
return foo is not null && Id == foo.Id;
}
public override int GetHashCode() => Id.GetHashCode();
}
record FooSummary(int Id, string Summary) : Foo(Id);
record FooDetail(int Id, string Detail) : Foo(Id);
var summary = new FooSummary(1, "Summary");
var detail = new FooDetail(1, "Detail");
Console.WriteLine(detail == summary);
// Output:
// foo IS null
// false
Is it possible to customize record equality is such a way that detail == summary
is true
?
In a class I could override Equals(object obj)
, but in a record that results in a compilation error (CS0111)
Edit
I've accepted @StriplingWarrior's answer as it technically answers my question, but as he and others have explained: this is a bad idea. This was definitely a case of the XY problem and trying to be a little too clever for my own good.
Upvotes: 0
Views: 5479
Reputation: 156634
Technically, you can, by overriding the ==
operators.
public record Foo(int Id)
{
public virtual bool Equals(Foo? foo)
{
return foo is not null && Id == foo.Id;
}
public override int GetHashCode() => Id.GetHashCode();
}
public record FooSummary(int Id, string Summary) : Foo(Id)
{
public bool Equals(FooDetail? other)
{
return base.Equals((Foo?)other);
}
public override int GetHashCode() => base.GetHashCode();
}
public record FooDetail(int Id, string Detail) : Foo(Id)
{
public bool Equals(FooSummary? other)
{
return base.Equals((Foo?)other);
}
public static bool operator ==(FooDetail? left, FooSummary? right)
=> (object?)left == right || (left?.Equals(right) ?? false);
public static bool operator !=(FooDetail? left, FooSummary? right)
=> !(left == right);
public static bool operator ==(FooSummary? left, FooDetail? right)
=> (object?)left == right || (left?.Equals(right) ?? false);
public static bool operator !=(FooSummary? left, FooDetail? right)
=> !(left == right);
public override int GetHashCode() => base.GetHashCode();
}
That doesn't mean it's a good idea. You'll get unexpected behaviors when your types are explicitly cast as the specific types you're trying to compare.
In my experience, when people are tempted to override equality operators, that's usually the wrong tool for what they're trying to accomplish.
Upvotes: 2