简体   繁体   English

C#中两个对象的等式比较

[英]Equality Comparison of two Objects in C#

This is a Fundamental type question, forgive me for being so amateurish. 这是一个基本类型的问题,原谅我是如此业余。

Case 1: 情况1:

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

Case2: 案例2:

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. 在第一个示例中, _emp1_emp2都指向同一个Employee实例,因此Equals返回true。

  • In your second example, you create two Employee objects, _emp1 and _emp2 being two distinctly different objects. 在第二个示例中,您创建了两个Employee对象, _emp1_emp2是两个截然不同的对象。 Therefore, Equals returns false. 因此, Equals返回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. 那么使用默认比较器的Equals将返回false,因为它们是两个唯一对象。

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. 此外,如果您(如您所愿)覆盖EqualsCompareTo的默认行为,则上述所有内容都没有实际意义。 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. 每次有new Employee()都会在堆和堆栈中分配新的内存。

means _emp1 is value in memory pointing to heap say 1212. 意味着_emp1是内存中指向堆的值1212。

Now you have second statement 现在你有第二个陈述

Employee _emp2 = new Employee();

So again new value _emp2 say 1414 in heap. 所以再次新值_emp2在堆中说1414。

That's why _emp1.Equals(_emp2) returns false here. 这就是_emp1.Equals(_emp2)在这里返回false的原因。

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. 您应该创建自己的Equals方法。 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) 默认情况下,从Object类调用Equals ,它基本上检查这两个引用是否指向一个对象(即Object.ReferenceEqual(object, object)是否被调用)

Employee , does not implement it's own .Equals() method, then it is using Object.Equals() , which is only comparing the references. Employee ,没有实现它自己的.Equals()方法,然后它使用Object.Equals() ,它只是比较引用。 In case 1, your two references are made equal when assigning. 在案例1中,分配时两个引用相同。

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. 如果.Equals()内部属性比较Employee对象,则应实现自己的.Equals()方法,如果所有这些属性值匹配则返回true,否则返回false。

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. 在第一种情况下,实例是相同的, _emp2_emp1您可以通过实现IEquatable<T>接口来实现。

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. 当您编写Employee _emp1您正在分配存储指针所需的内存,该指针将指向将包含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). 分配一个新的内存,用一个Employee实例填充它,并返回该内存的地址(指针)。 Something like, let's say, 1234567. So after Executing Employee _emp1 = new Employee(); 比如1234567。比如执行Employee _emp1 = new Employee(); , you have _emp1 equal to 1234567, and the memory pointed by 1234567 containing your Employee. ,你有_emp1等于1234567,以及包含你的员工的1234567指向的内存。

Then you execute Employee _emp2 = _emp1; 然后执行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. ,结果是另一块内存能够包含一个包含Employee( _emp2 )实例的内存的地址,该实例也等于1234567。 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. 这表示当你执行_emp1.Equals(_emp2)结果为真,因为你的两个变量都指向同一块内存。

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 . 在第二种情况下,创建另一个Employee实例并将其放入不同的内存块(例如7654321之类的内容),并将此地址分配给_emp2 ,因此与_emp1不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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