0

Give then following Class declaration:

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

I'm trying to use Employee.Equals(Employee) but for some reason it doesn't work:

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

As I'm casting b as Employee, I was expecting that Employee.Equals(Employee) would be called, since it matches the signature better then Employee.Equals(Object), but the latter is being called instead. What am I doing wrong?

Bruno Santos
  • 724
  • 7
  • 19

2 Answers2

2

In

private static void CompareObjects(Object a, Object b)

You use

a.Equals

However a is of type Object, so you're using Object.Equals(). You are calling the Equals() method of a, not of b.

If you expect both a and b to be of type Employee you could write

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

or

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

However, either variant will throw an Exception of a is not of type Employee.

Instead, consider

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

UPDATE

The signature of your Equals method is not correct if your intent is to override Object.Equals(object o). Your method Employee.Equals(Employee e) will still not be called as written. I would recommend the following pattern if you want to override Object.Equals(object o) and if you want things that are not employees never to be equal to things that are employees.

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. */;
}

Note that whenever you override the semantics of Equals() you almost certainly want to override GetHashCode() as well. See

Simplify Overriding Equals(), GetHashCode() in C# for Better Maintainability

Community
  • 1
  • 1
Eric J.
  • 147,927
  • 63
  • 340
  • 553
0

change the condition from this if (a.Equals(b as Employee))
to

if ((Employee)a.Equals(b as Employee))
Parv Sharma
  • 12,581
  • 4
  • 48
  • 80