C# 虚方法的重载解析

C# 虚方法的重载解析,c#,methods,virtual,overloading,C#,Methods,Virtual,Overloading,以代码为例 公共类基 { 公共虚拟整数添加(整数a、整数b) { 返回a+b; } } 派生的公共类:基 { 公共覆盖整数添加(整数a、整数b) { 返回a+b; } 公共整数相加(浮点a、浮点b) { 返回(Int32)(a+b); } } 如果我创建一个派生类的实例,并使用int类型的参数调用Add,那么为什么它使用float参数调用Add方法呢 Derived obj=new-Derived() 对象添加(3,5) //为什么打电话 添加(浮动a、浮动b) 为什么不调用更具体的方法?这

以代码为例

公共类基
{
公共虚拟整数添加(整数a、整数b)
{
返回a+b;
}
}
派生的公共类:基
{
公共覆盖整数添加(整数a、整数b)
{
返回a+b;
}
公共整数相加(浮点a、浮点b)
{
返回(Int32)(a+b);
}
}
如果我创建一个派生类的实例,并使用int类型的参数调用Add,那么为什么它使用float参数调用Add方法呢

Derived obj=new-Derived()
对象添加(3,5)
//为什么打电话
添加(浮动a、浮动b)

为什么不调用更具体的方法?

这是出于设计。C语言规范第7.5.3节规定:

例如,方法调用的候选集不包括标记为override的方法(§7.4),如果派生类中的任何方法适用(§7.6.5.1),则基类中的方法不是候选方法

换句话说,由于
派生的
类有一个非重写的
添加
方法,因此
基本
类中的
添加
方法(及其在
派生的
中的重写版本)不再是重载解析的候选方法

尽管
Base.Add(int,int)
会更好地匹配,但是
Derived.Add(float,float)
的存在意味着编译器甚至从未考虑基类方法

Eric Lippert在中讨论了这种设计的一些原因。


选择重载时,如果派生类中声明了任何兼容的方法,则忽略基类中声明的所有签名,即使它们在同一派生类中被重写

你怎么知道3和5是整数?试着指定它们的类型,看看会发生什么。你能编译这个吗?您可能会得到一些强制转换错误,如float到int?这不会编译,因为没有从float到int的隐式转换。您确定第二个Add方法返回int吗?@Ritch,@Matthew..即使您添加类似于
int a=3的内容,也没有任何区别;int b=5;增加(a、b)项也请阅读John Skeet的以下帖子。
+1回答得好。进一步阅读的证明、解释和链接。有没有办法在保持原始方法可见的同时为虚拟方法添加重载?