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

时间:2013-01-25 09:54:51

标签: c# equality

这是一个基本类型的问题,原谅我是如此业余。

案例1:

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

情况2:

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

你能解释一下上面的比较方法和内存映射和分配视角的原因吗?

7 个答案:

答案 0 :(得分:9)

简单来说,默认比较器会比较对象实例。

  • 在您的第一个示例中,_emp1_emp2都指向Employee的同一个实例,因此Equals返回true。

    < / LI>
  • 在第二个示例中,您创建了两个Employee个对象,_emp1_emp2是两个截然不同的对象。因此,Equals返回false。


请注意,对于引用类型,复制构造函数不会隐式调用。你做的是:

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

然后Equals使用默认比较器将返回false,因为它们是两个唯一对象。

另请注意,对于值类型,此行为不一样


此外,如果您(如您所愿)覆盖EqualsCompareTo的默认行为,则以上所有内容都没有实际意义。标准技术可能是(假设一点点):

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;
}

进一步阅读:

答案 1 :(得分:4)

Employee _emp1 = new Employee();

每次有new Employee()时,你都会在堆和堆栈中分配新的内存。

表示_emp1是内存中指向堆的值1212。​​

现在你有第二个陈述

Employee _emp2 = new Employee();

所以再次新值_emp2在堆中说1414。

这就是_emp1.Equals(_emp2)在这里返回false的原因。

当你说

_emp1 = _emp2

您在两者中分配相同的值。

答案 2 :(得分:2)

“这个苹果属于乔。这个梨属于同一个人。这个苹果的主人和这个梨的主人是同一个人吗?是的。”

“这个苹果属于苏珊。这个梨属于苏珊。这个苹果的主人和这个梨的主人是同一个人吗?不,他们恰好都被称为苏珊。”

答案 3 :(得分:1)

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

答案 4 :(得分:1)

Employee,没有实现它自己的.Equals()方法,然后使用Object.Equals(),它只是比较引用。在案例1中,分配时两个引用相同。

如果要根据内部属性比较Employee个对象,则应实现自己的.Equals()方法,如果所有这些属性值匹配则返回true,否则返回false。

答案 5 :(得分:1)

没有办法将两个单独的员工实例等同起来,你需要一种方法来等同他们是否平等,因为他们是单独的实例。在第一种情况下,实例相同且_emp2_emp1您可以通过实施IEquatable<T>界面来实现此目的。

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

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

然后你可以这样做

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

答案 6 :(得分:1)

当您编写Employee _emp1时,您正在分配将指针存储到另一块内存所需的内存,该内存将包含Employee实例。

new Employee();分配一个新的内存,用一个Employee实例填充它,并返回该内存的地址(指针)。比如说,1234567。所以在执行Employee _emp1 = new Employee();之后,你的_emp1等于1234567,并且1234567指向的内存包含你的员工。

然后你执行Employee _emp2 = _emp1;,结果就是让另一块内存能够包含一个包含Employee(_emp2)实例的内存的地址,该实例也等于1234567 。这表示当你执行_emp1.Equals(_emp2)时结果为真,因为你的两个变量都指向同一块内存。

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