为什么我必须覆盖虚方法而不是使用多态?

时间:2012-09-28 06:04:02

标签: c# polymorphism

我有一个名为Employee的班级。现在我尝试定义其Equals方法,但我想仅接受Employee作为参数。

所以我写这段代码:

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

但它不起作用!控制台输出:

false

不是我的预期:

Compare!
true

看起来我必须写public override bool Equals (Object),但为什么呢? C#不能选择按参数类型调用的方法吗?

3 个答案:

答案 0 :(得分:5)

尝试将代码更改为

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

正如您所说,它使用的是Object.Equals Method (Object, Object)

答案 1 :(得分:4)

  

我有一个名为Employee的类。现在我尝试定义它的Equals方法,但我想接受一个Employee作为参数。

然后你没有覆盖,你重载。这意味着任何想要调用代码 的东西必须根据参数的执行时类型动态地执行它,它必须知道你的重载之前时间并考虑到它。

如果您Employee实施IEquatable<Employee>,那么后者是可行的(您仍应覆盖GetHashCode,理想情况下覆盖Equals(object)理智) - 那么使用EqualityComparer<T>.Default的任何东西最终都会使用你的方法。这将包括Dictionary<,>等。

但基本上,期望能够调用Equals(object)的任何内容都将获得继承的实现,因为您没有覆盖它。 C#在执行时根本不执行重载解析,除非您使用dynamic类型的动态类型 - 这在其他方面具有重大影响,尤其是性能。

你有两个选择:

  • 使用具有不同规则的动态语言
  • 遵循C#的规则,其中在编译时选择方法签名,但该方法签名的实现被多态确定为执行时间

答案 2 :(得分:0)

你没有得到你期望的东西,因为你调用了不同的 Equals 方法)))你调用类 object 的方法,C#中所有类的父类,但是您希望您将调用Employee类的Equals方法。要调用Employee类的Equals方法,您应该使用Employee实例:

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