There is a nice explanation why object.ReferenceEquals(this, obj)
must not be used for value types:
When comparing values using ReferenceEquals, if objA and objB are value types, they are boxed before they are passed to the ReferenceEquals method. This means that even if both objA and objB represent the same instance of a value type, the ReferenceEquals method nevertheless returns false
However, I found code similar to the following snippet:
internal readonly struct Foo
{
public override bool Equals(object obj)
{
if (object.ReferenceEquals(this, obj))
{
return true;
}
if (obj is Foo other)
{
return this.Equals(other);
}
return false;
}
public bool Equals(Foo other)
{
// ..
return true;
}
}
Is this just wrong or is there an edge case in which ReferenceEquals
could be useful (i.e., evaluate to true) for value types, especially structs?
It shouldn't be. The code as-written is simply bad, in that it unnecessarily boxes something for a test that will never work. For completeness, a more useful and idiomatic pattern in this case would be:
// custom Foo equality implementation
public bool Equals(Foo other)
{
// ...
}
// default object implemenentation
public override int GetHashCode() {...} // must match Equals(Foo) logic
public override bool Equals(object obj) => obj is Foo other && Equals(other);