[英]Equality Comparison of two Objects in C#
这是一个基本类型的问题,原谅我是如此业余。
情况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 !!
你能解释一下上面的比较方法和内存映射和分配视角的原因吗?
简单来说,默认比较器比较对象实例。
在第一个示例中, _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,因为它们是两个唯一对象。
另外请注意,这种行为是不是值类型相同 。
此外,如果您(如您所愿)覆盖Equals
和CompareTo
的默认行为,则上述所有内容都没有实际意义。 标准技术可能是(假设一点点):
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;
}
进一步阅读:
Employee _emp1 = new Employee();
每次有new Employee()
都会在堆和堆栈中分配新的内存。
意味着_emp1是内存中指向堆的值1212。
现在你有第二个陈述
Employee _emp2 = new Employee();
所以再次新值_emp2在堆中说1414。
这就是_emp1.Equals(_emp2)在这里返回false的原因。
当你说
_emp1 = _emp2
您在两者中分配相同的值。
“这个苹果属于乔。这个梨属于同一个人。这个苹果的主人和这个梨主人是同一个人吗?是的。”
“这个苹果属于苏珊。这个梨属于苏珊。这个苹果的主人和这个梨的主人是同一个人吗?不,他们恰好都被称为苏珊。”
您应该创建自己的Equals
方法。 默认情况下,从Object
类调用Equals
,它基本上检查这两个引用是否指向一个对象(即Object.ReferenceEqual(object, object)
是否被调用)
Employee
,没有实现它自己的.Equals()
方法,然后它使用Object.Equals()
,它只是比较引用。 在案例1中,分配时两个引用相同。
如果.Equals()
内部属性比较Employee
对象,则应实现自己的.Equals()
方法,如果所有这些属性值匹配则返回true,否则返回false。
没有办法将两个单独的员工实例等同起来,你需要一种方法来等同它们是否相等,因为它们是单独的实例。 在第一种情况下,实例是相同的, _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);
当您编写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
不同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.