简体   繁体   中英

Equality Comparison of two Objects in C#

This is a Fundamental type question, forgive me for being so amateurish.

Case 1:

Employee _emp1 = new Employee();
Employee _emp2 = _emp1;
_emp1.Equals(_emp2) ==> RETURNS a True !!

Case2:

Employee _emp1 = new Employee();
Employee _emp2 = new Employee();
_emp1.Equals(_emp2) ==> RETURNS a False !!

Could you explain me the above Comparison method and reason interms of Memory-Mapping and allocation perspective ?

Simply speaking, the default comparator compares object instances.

  • In your first example, both _emp1 and _emp2 are pointing to the same instance of Employee and therefore Equals returns true.

  • In your second example, you create two Employee objects, _emp1 and _emp2 being two distinctly different objects. Therefore, Equals returns false.


Note that copy constructors are not implicitly called for reference types. Were you to do:

Employee _emp1 = new Employee();
Employee _emp2 = new Employee(_emp1); //or _emp1.Clone() if that is implemented

then Equals using a the default comparator will return false since they are two unique objects.

Also note that this behavior is not the same for value types.


Furthermore, if you (as you should) override the default behavior of Equals and CompareTo , all the above becomes moot. A standard technique might be (assuming a little bit):

public bool Equals(object rhs)
{
    var rhsEmployee = rhs as Employee;
    if(rhsEmployee == null) return false;

    return this.Equals(rhsEmployee);
}

public bool Equals(Employee rhs)
{
     return this.EmployeeId == rhs.EmployeeId;
}

Further reading:

Employee _emp1 = new Employee();

Everytime you have new Employee() you have new memory allocated in heap and stack.

means _emp1 is value in memory pointing to heap say 1212.

Now you have second statement

Employee _emp2 = new Employee();

So again new value _emp2 say 1414 in heap.

That's why _emp1.Equals(_emp2) returns false here.

when you say

_emp1 = _emp2

You are assigning the same values in both.

"This apple belongs to Joe. This pear belongs to the same man. Is this apple's owner the same person as this pear's owner? Yes."

"This apple belongs to Susan. This pear belongs to Susan. Is this apple's owner the same person as this pear's owner? No, they just happen to both be called Susan."

You should create your own Equals method. By default Equals is called from Object class, which is basically check if these two references points to one object (ie Object.ReferenceEqual(object, object) is called)

Employee , does not implement it's own .Equals() method, then it is using Object.Equals() , which is only comparing the references. In case 1, your two references are made equal when assigning.

If you want to compare the Employee objects by their internal properties, you should implement your own .Equals() method that returns true if all those properties values match, and false otherwise.

There is no way of equating the two seperate instances of employee, you need a way of equating whether they are equal because they are seperate instances. In case one, the instances are the same and _emp2 is _emp1 You can do this by implementing the IEquatable<T> interface.

public class Employee : IEquatable<Employee>
{
  public int Id { get; set; }

  public bool Equals(Employee other)
  {
    return other.Id == Id;
  } 
}

You can then do this

Employee e = new Employee() { Id = 1 };
Employee e2 = new Employee() { Id = 1 };
//Returns true
bool b = e.Equals(e2);

When you write Employee _emp1 you are allocating the memory which is needed to store a pointer to another piece of memory that will contain an instance of Employee.

new Employee(); allocates a new piece of memory filling it with an instance of Employee and return you the address of this memory (the pointer). Something like, let's say, 1234567. So after Executing Employee _emp1 = new Employee(); , you have _emp1 equal to 1234567, and the memory pointed by 1234567 containing your Employee.

Then you execute Employee _emp2 = _emp1; , and the result is having another piece of memory able to contain an address to a piece of memory containing an instance of Employee ( _emp2 ) which is equal to 1234567, too. This meand that when you execute _emp1.Equals(_emp2) the result is true, since both of your vars point to the same piece of memory.

In the second case, another instance of Employee is created and put in a different piece of memory (eg something like 7654321) and this address is assigned to _emp2 that hence is different from _emp1 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM