【问题标题】:Object.Equals return falseObject.Equals 返回 false
【发布时间】:2018-08-06 12:10:06
【问题描述】:

Object.Equals 总是返回 false,为什么不等于?

Student student = new Student(3, "Jack Poly");
Student otherStudent = (Student)student.Clone();
if (Object.Equals(student, otherStudent))
{
    Console.WriteLine("Equal");
}
else
 {
    Console.WriteLine("Not Equal");
 }

如下克隆方法

    public override StudentPrototype Clone()
    {
        return this.MemberwiseClone() as StudentPrototype;
    }

【问题讨论】:

  • 因为Clone 返回两个差异实例。即使这些实例具有相同的属性,它们也不相等,除非您适当地覆盖 Equals
  • 如果比较项是引用类型,则您正在进行深度克隆,object.equals 比较地址。

标签: c# oop prototype clone


【解决方案1】:

看看这个articleMSDN

如果当前实例是引用类型,Equals(Object) 方法 测试引用相等,并调用 Equals(Object) 方法 相当于调用 ReferenceEquals 方法。参考 相等意味着被比较的对象变量引用 同一个对象。

您的Student 是一个引用类型,克隆MemberwiseClone 返回一个新的另一个object

Student student = new Student(3, "Jack Poly");
Student otherStudent = (Student)student.Clone();

所以Equal 必须返回false

【讨论】:

    【解决方案2】:

    调用Clone 时,您将创建一个全新的类实例,该实例具有与原始类相同的属性和字段。见MSDN

    创建一个新对象,它是当前实例的副本

    这两个实例是完全独立的,即使它们在每个属性或字段上引用完全相同的值。特别是从一个更改属性不会影响另一个。

    另一方面,Equals 默认比较两个 references 是否相等,这在您的情况下显然是错误的。换句话说:仅仅因为你有两个叫 Marc 的学生并不意味着他们是同一个人。您必须实现平等的含义,例如通过比较姓氏或他们的学生身份号码或它们的组合。

    您可以在 Student-class 中覆盖 Equals

    class Student
    {
        public override bool Equals(object other)
        {
            var student = other as Student;
            if(student == null) return false;
            return this.Name == student.Name;
        }
    }
    

    并使用它:

    if (student.Equals(otherStudent)) ...
    

    【讨论】:

    • 您的Equals 示例有一个编译器警告,它隐藏了继承的Object.Equals。换句话说,Equals 的正确实现比您的示例复杂得多。
    猜你喜欢
    • 1970-01-01
    • 2019-06-27
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 2015-08-02
    • 2012-05-17
    • 2013-10-26
    • 2013-01-06
    相关资源
    最近更新 更多