Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IEquatable<T> - Best practice override for .Equals(object obj) in C#

Whenever I write a new class or struct that is likely to hold some data, that may need to be compared, I always implement IEquatable<T> as this provides the class/struct with a strongly typed .Equals(T other) method.

example:

public struct Radius : IEquatable<Radius>
{
    public Int32 TopLeft { get; set; }
    public Int32 TopRight { get; set; }
    public Int32 BottomLeft { get; set; }
    public Int32 BottomRight { get; set; }

    public bool Equals(Radius other)
    {
        return this.TopLeft == other.TopLeft
            && this.TopRight == other.TopRight
            && this.BottomLeft == other.BottomLeft
            && this.BottomRight == other.BottomRight;
    }
}

As well as providing an implementation for .Equals(Radius other), I should really override the default implementation too (.Equals(object obj))

I have two options here, and my question is, which of these implementations is better?

Option 1 is to use casting:

public override bool Equals(object obj)
{
    return this.Equals((Radius)obj);
}

Option 2 is to use the "as" keyword:

public override bool Equals(object obj)
{
    return this.Equals(obj as Radius);
}

My reason for asking this is, using casting will throw an exception if obj cannot be cast to Radius, whereas as will resolve to null if it cannot be cast, therefore it just checks this against null, without throwing an exception; So is it better to throw an exception, or to just return false?

EDIT: As it has been pointed out by quite a few fellow SO'ers, structs cannot be null, therefore the second option does not apply for a struct. Therefore another question springs to mind: Should the overridden implementation of .Equals(object obj) be identical for structs and classes?

like image 335
Matthew Layton Avatar asked Dec 21 '22 01:12

Matthew Layton


1 Answers

The Equals() method must never throw an exception.

An object of a different type is merely unequal.

Quoting the documentation:

Implementations of Equals must not throw exceptions; they should always return a value. For example, if obj is null, the Equals method should return false instead of throwing an ArgumentNullException.

like image 138
SLaks Avatar answered Feb 12 '23 11:02

SLaks