Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Value vs Reference

Tags:

c#

reference

What decision should I take about Equals(), ReferenceEquals(), and == from the following results? What do they produce actually?

#region
int integer = 1;
int integer2 = integer;

bool referenceEquality = (integer == integer2);//true
bool valueEquality = integer.Equals(integer2);//true
bool valueEqualityMore = object.Equals(integer, integer2);//true
bool valueEqualityMoreMore = object.ReferenceEquals(integer, integer2);//false
#endregion

#region
int integer = 1;
int integer2 = 1;

bool referenceEquality = (integer == integer2);//true
bool valueEquality = integer.Equals(integer2);//true
bool valueEqualityMore = object.Equals(integer, integer2);//true
bool valueEqualityMoreMore = object.ReferenceEquals(integer, integer2);//false
#endregion

#region
MyClass obj = new MyClass(1, "Hello");
MyClass obj2 = obj;

bool referenceEquality = (obj == obj2);//true
bool valueEquality = obj.Equals(obj2);//true
bool valueEqualityMore = object.Equals(obj, obj2);//true
bool valueEqualityMoreMore = object.ReferenceEquals(obj, obj2);//true            
#endregion

#region
MyClass obj = new MyClass(1, "Hello");
MyClass obj2 = new MyClass(1, "Hello");

bool referenceEquality = (obj == obj2);//false
bool valueEquality = obj.Equals(obj2);//false
bool valueEqualityMore = object.Equals(obj, obj2);//false
bool valueEqualityMoreMore = object.ReferenceEquals(obj, obj2);//false
#endregion

Hell! I understand nothing.

To me referenceEquals() of the 1st block should return true. == in the second block should return false (as the references are different). And, both of the Equals() in the 4th block should return true (as their values are same).

like image 260
user366312 Avatar asked May 24 '26 15:05

user366312


1 Answers

The first point of confusion you seem to be having is that with value types, i.e. int, float, DateTime, the == operator is value equality. With reference types, == is (by default, see below) reference equality. This would explain the disparity of answers in your first two integer cases.

Secondly, the default implementation of Equals() tests reference equality, not value equality. So since it appears that MyClass doesn't override Equals(), that explains the disparity of answers between your reference cases.

Additionally, many reference types, such as String, override the == operator to provide value-equality semantics. So your best bet, until you memorize which types are which, is to look up the documentation.

In short:

  • Value types
    • == is value-equality (for framework types)
    • Not a reference type, so reference equality is meaningless
  • Reference types
    • ReferenceEquals() is always reference equality
    • == is reference equality by default, but can be (and often is for framework types) overridden to provide value equality
    • Equals() is reference equality by default, but can be (and often is for framework types) overridden to provide value equality
like image 168
Lee Avatar answered May 26 '26 03:05

Lee