Lai Yu-Hsuan
Lai Yu-Hsuan

Reputation: 28081

Why do I have to override virtual method instead of using polymorphism?

I have a class named Employee. Now I try to define its Equals method, but I want to accept an Employee as parameter only.

So I write this code:

class MainClass
    {
        public static void Main (string[] args)
        {
            Employee e = new Employee();
            Employee e2 = new Employee();
            Console.WriteLine(Equals(e, e2));
        }

        public static Employee CreateEmployee()
        {
            return new Employee();
        }
    } 

    class Employee
    {
        public int ID;
        public bool Equals (Employee e)
        {
            Console.WriteLine("Compare!");
            return ID == e.ID;
        }
    }

But it doesn't work! The console outputs:

false

Not what I expected:

Compare!
true

It looks like that I have to write public override bool Equals (Object), but why? Can't C# choose the method to call by the type of parameter(s)?

Upvotes: 0

Views: 214

Answers (3)

Dmytro
Dmytro

Reputation: 17176

You don't get what you expect because you call different Equals methods ))) You call method of class object, the parent class for all classes in C#, but You expect that You will call Equals method of Employee class. To call Equals method of Employee class you should use Employee instance:

Employee e1 = new Employee();
Employee e2 = new Employee();
Console.WriteLine(e1.Equals(e2));

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500525

I have a class named Employee. Now I try to define its Equals method, but I want to accept an Employee as parameter only.

Then you're not overriding, you're overloading. That means anything which wants to call your code either has to do it dynamically based on the execution-time types of the parameters, or it has to know about your overload ahead of time and take account of it.

The latter is feasible if you make Employee implement IEquatable<Employee> (and you should still override GetHashCode, and ideally also override Equals(object) for sanity) - then anything which uses EqualityComparer<T>.Default will end up using your method. That would include Dictionary<,> etc.

But basically, anything which expects to be able to call Equals(object) will get the inherited implementation, because you haven't overridden it. C# simply doesn't perform overload resolution at execution time, unless you're using dynamic typing with the dynamic type - which has significant impact in other ways, not least performance.

You have two options, really:

  • Use a dynamic language which has different rules
  • Follow the rules of C#, where the method signature is chosen at compile-time, but the implementation of that method signature is determined as execution time polymorphically

Upvotes: 4

Adriaan Stander
Adriaan Stander

Reputation: 166396

Try changing your code to

Console.WriteLine(e.Equals(e2)); 

As you had it it was using Object.Equals Method (Object, Object)

Upvotes: 5

Related Questions