【问题标题】:Method overloading and inheritance方法重载和继承
【发布时间】:2017-01-07 02:34:47
【问题描述】:

我有以下课程:

public class BaseRepository
{
    public virtual void Delete(int id)
    {
        Console.WriteLine("Delete by id in BaseRepository");
    }
}

public class EFRepository: BaseRepository
{
    public override void Delete(int id)
    {
        Console.WriteLine("Delete by Id in EFRepository");
    }

    public void Delete(object entity)
    {
        Console.WriteLine("Delete by entity in EFRepository");
    }
}

然后我像这样使用它:

var repository = new EFRepository();
int id = 1;
repository.Delete(id);

为什么在这种情况下只有EFRepository.Delete(object entity) 会打电话?

【问题讨论】:

  • object 可以容纳一个 int。
  • @TravisJ 我很清楚,但问题有点不同

标签: c# inheritance overloading


【解决方案1】:

基本上,方法调用在 C# 中的工作方式是编译器首先查看最派生的类,然后查看是否有任何 新声明的 方法(不包括覆盖)适用于称呼。如果至少有一种适用的方法,那么重载解决方案会找出最好的方法。如果没有,它会尝试基类,依此类推。

我同意这令人惊讶 - 这是为了解决“脆弱的基类”问题,但我个人更希望将任何 覆盖 方法包含在候选集中。

方法调用在 C# 5 规范的第 7.6.5.1 节中进行了描述。这里的相关部分是:

  • 候选方法集被缩减为仅包含来自最派生类型的方法:对于集合中的每个方法C.F,其中C 是声明方法F 的类型,声明所有方法在C 的基本类型中从集合中删除。此外,如果C 是对象以外的类类型,则接口类型中声明的所有方法都将从集合中删除。 (仅当方法组是对具有除 object 之外的有效基类和非空有效接口集的类型参数的成员查找结果时,后一条规则才有效。)

并且在 7.4 的成员查找部分,override 方法被显式删除:

包含override 修饰符的成员被排除在集合之外。

【讨论】:

  • 感谢您的解释。所以,没有办法直接调用带int参数的方法吧?
  • @MegaTron:你必须先转换到 BaseRepository。
  • 谢谢。我认为改变这种设计会更好
  • 短语“新声明的方法(不仅仅是覆盖的方法)”是否排除了覆盖的方法?如果是这样,“公正”会让人感到困惑。
【解决方案2】:

因为:public override void Delete(int id) 将只覆盖基类方法:public virtual void Delete(int id)。

虽然 public void Delete(object entity) 是 EFRepository 类方法,所以当你执行 从 EFRepository 对象的方法时,它会调用自己的方法 strong> 这不过是 public void Delete(object entity)

【讨论】:

    猜你喜欢
    • 2011-02-27
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    相关资源
    最近更新 更多