Overriding Equals method in Structs

I've looked for overriding guidelines for structs, but all I can find is for classes.

At first I thought I wouldn't have to check to see if the passed object was null, as structs are value types and can't be null. But now that I come to think of it, as equals signature is

public bool Equals(object obj)

it seems there is nothing preventing the user of my struct to be trying to compare it with an arbitrary reference type.

My second point concerns the casting I (think I) have to make before I compare my private fields in my struct. How am I supposed to cast the object to my struct's type? C#'s as keyword seems only suitable for reference types.


Solution 1:

struct MyStruct 
{
   public override bool Equals(object obj) 
   {
       if (!(obj is MyStruct))
          return false;

       MyStruct mys = (MyStruct) obj;
       // compare elements here

   }

}

Solution 2:

Thanks to pattern matching in C# 7.0 there is an easier way to accomplish the accepted answer:

struct MyStruct 
{
    public override bool Equals(object obj) 
    {
        if (!(obj is MyStruct mys)) // type pattern here
            return false;

        return this.field1 == mys.field1 && this.field2 == mys.field2 // mys is already known here without explicit casting
    }
}

You could also make it even shorter as an expression-bodied function:

struct MyStruct 
{
    public override bool Equals(object obj) => 
        obj is MyStruct mys
            && mys.field1 == this.field1
            && mys.field2 == this.field2;
}

Solution 3:

I suppose, if one's using .NET 4.5, one can use the default implementation as noted in the documentation:

When you define your own type, that type inherits the functionality defined by the Equals method of its base type.

ValueType.Equals: Value equality; either direct byte-by-byte comparison or field-by-field comparison using reflection.