Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Diving into Equals method vs. == operator (II)

0.00/5 (No votes)
18 Nov 2016 1  
Equals method vs. == operator - Part II

In my previous post, I was talking about a particular error in one of my company's applications with regard to this issue. Now, I'm going to set out a little code demo to test results using different cases. So, here is my EqualsExample demo class code as long as two new "MiniBlog" dummy classes, MiniBlogDummyObject and MiniBlogDummyObjectOverloaded, to participate in the test:

MiniBlogDummyObject is a simple class that just overrides "Equals" method to set equality regarding "Value" public property. It doesn't overload "==" operator.

public class MiniBlogDummyObject
    {
        private string _value;

        public string Value { 
            set {_value=value; }
            get {return _value;} 
        }

        public MiniBlogDummyObject(string value)
        {
            _value = value;
        }

        public override bool Equals(object obj)
        {
            return this.Value == (obj as MiniBlogDummyObject).Value;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }

MiniBlogDummyObjectOverloaded is another class that overrides "Equals" method to set equality regarding "Value" public property and overloads "==" operator comparing values in the same "Value" property.

public class MiniBlogDummyObjectOverloaded
    {
        private string _value;

        public string Value { 
            set {_value=value; }
            get {return _value;} 
        }

        public MiniBlogDummyObjectOverloaded(string value)
        {
            _value = value;
        }

        public override bool Equals(object obj)
        {
            return this.Value == (obj as MiniBlogDummyObjectOverloaded).Value;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        // Overload Equality operator.
        public static bool operator ==(MiniBlogDummyObjectOverloaded x, MiniBlogDummyObjectOverloaded y)
        {
            return x.Value == y.Value;
        }

        // Overload Equality operator.
        public static bool operator !=(MiniBlogDummyObjectOverloaded x, MiniBlogDummyObjectOverloaded y)
        {
            return x.Value != y.Value;
        }
    }

Here is the code (and comments with the results) to test four different cases using:

  1. object type
  2. string type
  3. MiniBlogDummyObject
  4. MiniBlogDummyObjectOverloaded

Each case will be tested using two different instances of the same class by comparing them with both "Equals" method and "==" operator.

class EqualsExample
{
    static void Main(string[] args)
    {
        string separator = Environment.NewLine + "--------------------------" + Environment.NewLine;

        Console.WriteLine("WORKING WITH \"EQUALS\" METHOD AND \"==\" OPERATOR");
        Console.WriteLine(separator);

        #region Comparison 1

        object a1 = new string(new char[] { 'M', 'i', 'n', 'i', 'b', 'l', 'o', 'g' });
        object b1 = new string(new char[] { 'M', 'i', 'n', 'i', 'b', 'l', 'o', 'g' });
        Console.WriteLine("Comparison 1. \"a1\" and \"b1\" are OBJECT types: " + Environment.NewLine);
        Console.WriteLine("a1: {0}", a1.ToString());
        Console.WriteLine("b1: {0}", b1.ToString());
        Console.WriteLine();

        /* False. It compares references because a1 and b1 are object types. 
           So, references are different. */
        Console.WriteLine("a1 == b1 -> {0}", a1 == b1);
        /* True. It compares values, which are equals. */
        Console.WriteLine("a1.Equals(b1) -> {0}", a1.Equals(b1));
        Console.WriteLine(separator);

        #endregion

        #region Comparison 2

        string a2 = new string(new char[] { 'M', 'i', 'n', 'i', 'b', 'l', 'o', 'g' });
        string b2 = new string(new char[] { 'M', 'i', 'n', 'i', 'b', 'l', 'o', 'g' });
        Console.WriteLine("Comparison 2. \"a2\" and \"b2\" are STRING types: " + Environment.NewLine);
        Console.WriteLine("a2: {0}", a2.ToString());
        Console.WriteLine("b2: {0}", b2.ToString());
        Console.WriteLine();

        /* True. "String" class overloads "==" operator, so it compares values, not references  */
        Console.WriteLine("a2 == b2 -> {0}", a2 == b2);
        /* True. It compares values, which are equals. */
        Console.WriteLine("a2.Equals(b2) -> {0}", a2.Equals(b2));
        Console.WriteLine(separator);

        #endregion

        #region Comparison 3

        MiniBlogDummyObject a3 = new MiniBlogDummyObject("MiniBlog");
        MiniBlogDummyObject b3 = new MiniBlogDummyObject("MiniBlog");
        Console.WriteLine("Comparison 3. \"a3\" and \"b3\" are MiniBlogDummyObject types: " + 
                           Environment.NewLine);
        Console.WriteLine("a3: {0}", a3.Value);
        Console.WriteLine("b3: {0}", b3.Value);
        Console.WriteLine();

        /* False. "MiniBlogDummyObject " class doesn't overload "==" operator, 
           so it compares references, not values  */
        Console.WriteLine("a3 == b3 -> {0}", a3 == b3);
        /* True. It compares values, which are equals. */
        Console.WriteLine("a3.Equals(b3) -> {0}", a3.Equals(b3));
        Console.WriteLine(separator);

        #endregion

        #region Comparison 4

        MiniBlogDummyObjectOverloaded a4 = new MiniBlogDummyObjectOverloaded("MiniBlog");
        MiniBlogDummyObjectOverloaded b4 = new MiniBlogDummyObjectOverloaded("MiniBlog");
        Console.WriteLine("Comparison 4. \"a4\" and \"b4\" are MiniBlogDummyObjectOverloaded types: " + 
                           Environment.NewLine);
        Console.WriteLine("a4: {0}", a4.Value);
        Console.WriteLine("b4: {0}", b4.Value);
        Console.WriteLine();

        /* True. "MiniBlogDummyObjectOverloaded" class overloads "==" operator, 
	   so it compares according to that overloaded method, in this case over "Value" property. */
        Console.WriteLine("a4 == b4 -> {0}", a4 == b4);
        /* True. It compares values, which are equals. */
        Console.WriteLine("a4.Equals(b4) -> {0}", a4.Equals(b4));
        Console.WriteLine(separator);

        #endregion

        Console.ReadLine();
    }
}

As you can see, by running the code above, the results are:

  1. Object Type
    • Comparing with "==" operator: False. It compares references because a1 and b1 are plain object types. So, references are different.
    • Comparing with "Equals" method: True. It compares underlying values, which are equals.
  2. String Type
    • Comparing with "==" operator: True. "String" class overloads "==" operator, so it compares values, not references
    • Comparing with "Equals" method: True. It compares underlying values, which are equals.
  3. MiniBlogDummyObject
    • Comparing with "==" operator: False. "MiniBlogDummyObject" class doesn't overload "==" operator, so it compares references, not values
    • Comparing with "Equals" method: True. It compares values, which are equals.
    • MiniBlogDummyObjectOverloaded
      • Comparing with "==" operator: True. "MiniBlogDummyObjectOverloaded" class overloads "==" operator, so it compares according to that overloaded method, in this case over "Value" property.
      • Comparing with "Equals" method: True. It compares values, which are equals.

Demo Results

I hope you have a better understanding of this issue. If not, please comment below.

Regards!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here