方法重载和继承
Posted
技术标签:
【中文标题】方法重载和继承【英文标题】: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 我很清楚,但问题有点不同 【参考方案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)
【讨论】:
以上是关于方法重载和继承的主要内容,如果未能解决你的问题,请参考以下文章