3

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

情况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 !!

你能从内存映射和分配角度解释一下上述比较方法和原因吗?

4

7 回答 7

9

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

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

  • 在第二个示例中,您创建了两个Employee对象,_emp1并且_emp2是两个截然不同的对象。因此,Equals返回 false。


请注意,复制构造函数不会为引用类型隐式调用。你要这样做:

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

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

另请注意,对于值类型,此行为是不同的。


此外,如果您(如您所愿)覆盖 and 的默认行为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;
}

进一步阅读:

于 2013-01-25T09:57:39.957 回答
4
Employee _emp1 = new Employee();

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

表示 _emp1 是内存中指向堆的值,例如 1212。

现在你有第二个声明

Employee _emp2 = new Employee();

因此,新值 _emp2 在堆中再次说 1414。

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

当你说

_emp1 = _emp2

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

于 2013-01-25T10:06:55.933 回答
2

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

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

于 2013-01-25T09:57:10.217 回答
1

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

于 2013-01-25T09:57:18.617 回答
1

Employee, 没有实现它自己的.Equals()方法,然后它正在使用Object.Equals(),它只是比较引用。在情况 1 中,您的两个参考在分配时是相等的。

如果你想Employee通过它们的内部属性来比较对象,你应该实现你自己的.Equals()方法,如果所有这些属性值都匹配,则返回 true,否则返回 false。

于 2013-01-25T10:00:27.107 回答
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);
于 2013-01-25T10:00:39.353 回答
1

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

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

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

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

于 2013-01-25T10:09:24.640 回答