Click here to Skip to main content
15,890,436 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi, there are basically 3 types of equal check in c# object.ReferenceEquals,
a.Equals(b) and operator ==, I have understood the former 2, but so far I have not fully understood the exact meaning of ==, it is said that it is compared the reference identity, but it is not easy for me to get a clear picture for some cases, e.g.

int i1 = 1;
double d1 = 1;
Trace.WriteLine(" ReferenceEqual: " + object.ReferenceEquals(i1, d1)
      + ", \n i1==d1: " + (i1 == d1).ToString()
      + ", \n i1.equals(d1): " + i1.Equals(d1).ToString());


the output is:

ReferenceEqual: False,
i1==d1: True,
i1.equals(d1): False


here i1 == d1 is true. how to understand it correctly?
thanks.

What I have tried:

see the code above for details.
Posted
Updated 12-Jan-21 0:02am
v2

There are many things here you need to learn.
First off, "==" is an equality comparison, not a reference comparison. That means that for value types it compares actual values, implicitly casting as needed (so your int value becomes a double temporarily).

Secondly int and double are value types, and that means that in order to compare them using ReferenceEquals they need to be "boxed" - which means that a copy of the value they hold is encapsulated in a temporary reference type class and located on the heap. The two boxed references are then compared and will always give false.
Even if you simplify the code, you will always get false:
C#
public static void Main()
    int x = 1;
    Console.WriteLine(object.ReferenceEquals(x, x));
}
Even if you reduce it to it's most basic:
C#
public static void Main()
{
    Console.WriteLine(object.ReferenceEquals(666, 666));
}
You will always get false because the references to the boxed values are not the same.
ReferenceEquals will only ever give true for reference types (including strings) but even then, you will get strange results:
C#
Console.WriteLine(object.ReferenceEquals("ABC", "ABC"));
Will give true, as will
C#
string s1 = "ABC";
string s2 = "ABC;
Console.WriteLine(object.ReferenceEquals(s1, s2));
And so will
C#
string s1 = "ABC";
string s2 = s1.Replace("X", "Y");
Console.WriteLine(object.ReferenceEquals(s1, s2));
but that's a special case due to string interning.
You really need to understand the difference between value and reference types to know what you are doing with your code! Have a look here: Using struct and class - what's that all about?[^] but don't worry if it's a bit advanced for you!
 
Share this answer
 
Comments
Member 14707431 12-Jan-21 6:13am    
thanks a lot, what about .Equal(), you did not mention about it. Can you also give some words for it too?
OriginalGriff 12-Jan-21 6:33am    
That gets horribly complicated, because Equals is a virtual method, so it's implementation is down the the class or struct that is to the left of the dot operator.
This may help: https://docs.microsoft.com/en-us/dotnet/api/system.object.equals?view=net-5.0
Or it may confuse you further!
Most value types don't override Equals, so generally speaking Equals ends up being a "==" comparison on boxed values and you end up with false, unless the types are the same in which case you get a value comparison!

Don't spend too long on this: it will hurt your head after a while!
(It still makes my brain hurt working out what is boxed / unboxed and actually comared!):laugh:

If you want to know the real, full details, then start looking at the Reference Sources: they contain the actual code that the framework uses:
https://referencesource.microsoft.com/#mscorlib/system/object.cs,f2a579c50b414717,references

But expect to start chasing your tail for a while - RuntimeHelpers.cs is not exactly friendly...
Member 14707431 12-Jan-21 6:49am    
Good, even you did not give me a full clear comment, but I do get better understanding of .Equal(). Thanks a lot! I agree that such things are really confusing :). I think at least I should understand it to some degree so that I can have a comfortable feeling.
2 things:
1. Try the same experiment with strings.
2. Read about reference types and Value types

Here: Value Type and Reference Type[^]
example type: int
Quote:
A data type is a value type if it holds a data value within its own memory space. It means the variables of these data types directly contain values.

Quote:
a reference type doesn't store its value directly. Instead, it stores the address where the value is being stored.

example type: string

Quote:
If the current instance is a reference type, the Equals(Object) method tests for reference equality, and a call to the Equals(Object) method is equivalent to a call to the ReferenceEquals method. Reference equality means that the object variables that are compared refer to the same object.

i1==d1: True,

Works at value and thus returns true.

Read more: Remarks section: Object.Equals Method (System) | Microsoft Docs[^]
 
Share this answer
 
Comments
Member 14707431 12-Jan-21 5:59am    
thanks, Sandeep. I search also internet for some discussions. I found the following comments, which seem to be also helpful:

== Operator

If operands are Value Types and their values are equal, it returns true else false.
If operands are Reference Types with exception of string and both refer to the same instance (same object), it returns true else false.
If operands are string type and their values are equal, it returns true else false.


.Equals

If operands are Reference Types, it performs Reference Equality that is if both refer to the same instance (same object), it returns true else false.
If Operands are Value Types then unlike == operator it checks for their type first and if their types are same it performs == operator else it returns false.
Member 14707431 12-Jan-21 6:03am    
based above comments, it seems logical now:
i1 == d1: true, since it is value type and the same, therefore, true.
i1.Equals(d1): false, because .Equals() also check the type, since they have different types, int and double, therefore, false.

not sure whether you have different opinions.
OriginalGriff 12-Jan-21 6:04am    
"Try the same experiment with strings."
Please don't suggest that - string interning means it gets even more confusing! :laugh:
Member 14707431 12-Jan-21 6:07am    
yes, string has again one more special treatment on top of that.
Sandeep Mewara 12-Jan-21 6:23am    
Okie dokie. I wanted OP to see more variation of the things because of types involved.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900