Overriding the == operator in immutable types

MSDN recommendations for overloading Equals () and Operator == state:

By default, the == operator checks reference equality by determining if two links point to the same object, so reference types are not needed to implement the == operator to get this functionality. When the type is immutable, which means the data contained in the instance cannot be changed, the == operator is overloaded; compare the value of equality instead of referential equality can be useful because, as immutable objects, they can be considered the same as long as they have the same value . Overriding the == operator in immutable types is not recommended.

Can someone explain the arguments in bold?

EDIT . Also, is this manual only for the == operator, or is it also for the Equals method?

+6
equality immutability c # operator-overloading
source share
2 answers

My educated guess was to make things work like built-in types in .NET, namely that == should work as reference equality, where possible, and that Equals should work as equivalent equality, where possible. Consider the actual difference between == and Equals :

 object myObj = new Integer(4); object myObj2 = new Integer(4); //Note that == is only called if the ref'd objects are cast as a type //overloading it. myObj == myObj2; //False (???) myObj.Equals(myObj2); //True (This call is virtual) //Set the references equal to each other -- note that the operator== //comparison now works. myObj2 = myObj; myObj == myObj2; //True myObj.Equals(myObj2); //True 

This behavior, of course, is inconsistent and confusing, especially for new programmers, but it demonstrates the difference between comparative comparisons and value comparisons.

If you follow this MSDN guide, you follow the guide made by important classes such as string. Basically, if a comparison using == succeeds, the programmer knows that this comparison will always succeed if the links are not tied to new objects. The programmer need not worry that the contents of the objects are different because they will never be different:

 //Mutable type var mutable1 = new Mutable(1); var mutable2 = mutable1; mutable1 == mutable2; //true mutable1.MutateToSomethingElse(56); mutable1 == mutable2; //still true, even after modification //This is consistent with the framework. (Because the references are the same, //reference and value equality are the same.) Consider if == were overloaded, //and there was a difference between reference and value equality: var mutable1 = new Mutable(1); var mutable2 = new Mutable(1); mutable1 == mutable2; //true mutable1.MutateToSomethingElse(56); mutable1 == mutable2; //oops -- not true anymore //This is inconsistent with, say, "string", because it cannot mutate. 

This boils down to the fact that there is no real technical reason for leadership - it just has to stay in line with the rest of the classes within.

+16
source share

Suppose you have a mutable type A, and you create a collection or objects of type A. Adding an object to the collection should fail if that object already exists in the collection.

Now suppose you add an object to a set, and then change its properties so that it becomes equal to another object in the set. You created an invalid state in which there are two objects in the set that are equal.

0
source share

All Articles