You should not overload == it leads to code that is unintuitive. Just stick to overriding Equals (and GetHashCode)
Taken from Overloading operator== versus Equals() (Samuel Neff's answer)
When you have the expression
x == y
The method that will be used to compare variables x and y is decided at compile time. This is operator overloading. The type used when declaring x and y is used to define which method is used to compare them. The actual type within x and y (i.e., a subclass or interface implementation) is irrelevant. Consider the following.
object x = "hello"; object y = 'h' + "ello"; // ensure it's a different reference
x == y // evaluates to FALSE
and the following
string x = "hello"; string y = 'h' + "ello"; // ensure it's a different reference
x == y // evaluates to TRUE
This demonstrates that the type used to declare the variables x and y is used to determine which method is used to evaluate ==.
By comparison, Equals is determined at runtime based on the actual type within the variable x. Equals is a virtual method on Object that other types can, and do, override. Therefore the following two examples both evaluate to true.
object x = "hello"; object y = 'h' + "ello"; // ensure it's a different reference
x.Equals(y) // evaluates to TRUE
and the following
string x = "hello"; string y = 'h' + "ello"; // ensure it's a different reference
x.Equals(y) // also evaluates to TRUE