0

然后给出以下类声明:

   class Employee {
        public string Name { get; set; }
        public int Age { get; set; }

        public override bool Equals(object obj)
        {
            Console.WriteLine("In Equals(Object)");

            if (obj is Employee)
                if (this.Name == (obj as Employee).Name && this.Age == (obj as Employee).Age)
                    return true;
                else
                    return false;
            else
                return false;
        }

        public bool Equals(Employee obj)
        {
            Console.WriteLine("In Equals(Employee)");

            return this.Equals(obj as Object);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }

我正在尝试使用 Employee.Equals(Employee) 但由于某种原因它不起作用:

    private static void CompareObjects(Object a, Object b)
    {        
        if (a.Equals(b as Employee)) Console.WriteLine("a.Equals(b) returns true");
        else Console.WriteLine("a.Equals(b) returns false");
    }

当我将 b 转换为 Employee 时,我期望 Employee.Equals(Employee) 会被调用,因为它比 Employee.Equals(Object) 更好地匹配签名,但后者被调用了。我究竟做错了什么?

4

2 回答 2

2

private static void CompareObjects(Object a, Object b)

你用

a.Equals

但是a是 Object 类型,因此您使用的是 Object.Equals()。 您正在调用 的 Equals() 方法a,而不是 的b

如果您期望两者都a属于b类型,则Employee可以编写

if (((Employee)a).Equals(b)) Console.WriteLine("a.Equals(b) returns true");

或者

if ((a as Employee).Equals(b)) Console.WriteLine("a.Equals(b) returns true");

a但是,任何一种变体都会抛出不是 Employee 类型的异常。

相反,考虑

Employee aEmployee = a as Employee;
if (aEmployee != null) 
{
    if (aEmployee.Equals(b)) Console.WriteLine("a.Equals(b) returns true");
}

更新

如果您的意图是覆盖,则 Equals 方法的签名不正确Object.Equals(object o)。您的方法Employee.Equals(Employee e)仍然不会被称为书面。如果您想覆盖Object.Equals(object o)并且如果您希望非员工的事物永远不等于员工的事物,我会推荐以下模式。

public override bool Equals(object obj)
{
    // If the references are equal, objects must be equal
    if (object.ReferenceEquals(this, obj)) return true;

    Employee other = obj as Employee;

    // obj is not able to be cast to Employee, no need to compare further
    if (other == null) return false;

    // Here, implement the checks you need to compare two 
    // Employee instances for equality
    return this.FirstName == other.FirstName /* && etc. */;
}

请注意,每当您覆盖语义时,Equals()您几乎肯定也想覆盖GetHashCode()。看

在 C# 中简化覆盖 Equals()、GetHashCode() 以获得更好的可维护性

于 2012-07-10T07:04:20.503 回答
0

将条件从这里更改 if (a.Equals(b as Employee))

if ((Employee)a.Equals(b as Employee))
于 2012-07-10T07:12:52.973 回答