Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between == and Equals() for primitives in C#?

Tags:

c#

compare

Consider this code:

int age = 25; short newAge = 25; Console.WriteLine(age == newAge);  //true Console.WriteLine(newAge.Equals(age)); //false Console.ReadLine(); 

Both int and short are primitive types, but a comparison with == returns true and a comparison with Equals returns false.

Why?

like image 230
Mohammad Zargarani Avatar asked Jan 22 '14 03:01

Mohammad Zargarani


People also ask

What is the difference between == and Equals () method?

== should be used during reference comparison. == checks if both references points to same location or not. equals() method should be used for content comparison. equals() method evaluates the content to check the equality.

What is the difference between == and Equals () in C#?

Difference between == and . Equals method in c# The Equality Operator ( ==) is the comparison operator and the Equals() method in C# is used to compare the content of a string. The Equals() method compares only content.

What is the difference between == operator and Equals () in String wrapper classes?

== is a reference comparison, i.e. both objects point to the same memory location. . equals() evaluates to the comparison of values in the objects.

Can we compare primitive data types using ==?

Primitives. Like in other languages, we can compare the values of primitives with the < , > , <= , and >= operator. The same problems of floating-point data types apply to them, so be aware. Also, boolean isn't comparable except for equality with == and !=


1 Answers

Short answer:

Equality is complicated.

Detailed answer:

Primitives types override the base object.Equals(object) and return true if the boxed object is of the same type and value. (Note that it will also work for nullable types; non-null nullable types always box to an instance of the underlying type.)

Since newAge is a short, its Equals(object) method only returns true if you pass a boxed short with the same value. You're passing a boxed int, so it returns false.

By contrast, the == operator is defined as taking two ints (or shorts or longs).
When you call it with an int and a short, the compiler will implicitly convert the short to int and compare the resulting ints by value.

Other ways to make it work

Primitive types also have their own Equals() method that accepts the same type.
If you write age.Equals(newAge), the compiler will select int.Equals(int) as the best overload and implicitly convert short to int. It will then return true, since this method simply compares the ints directly.

short also has a short.Equals(short) method, but int cannot be implicitly converted to short, so you aren't calling it.

You could force it to call this method with a cast:

Console.WriteLine(newAge.Equals((short)age)); // true 

This will call short.Equals(short) directly, without boxing. If age is larger than 32767, it will throw an overflow exception.

You could also call the short.Equals(object) overload, but explicitly pass a boxed object so that it gets the same type:

Console.WriteLine(newAge.Equals((object)(short)age)); // true 

Like the previous alternative, this will throw an overflow if it doesn't fit in a short. Unlike the previous solution, it will box the short into an object, wasting time and memory.

Source Code:

Here are both Equals() methods from the actual source code:

    public override bool Equals(Object obj) {         if (!(obj is Int16)) {             return false;         }         return m_value == ((Int16)obj).m_value;     }      public bool Equals(Int16 obj)     {         return m_value == obj;     } 

Further Reading:

See Eric Lippert.

like image 184
SLaks Avatar answered Sep 24 '22 16:09

SLaks