2011-07-22 28 views
10

考虑代码重载决策

public class Base 
{ 
    public virtual int Add(int a,int b) 
    { 
     return a+b; 
    } 
} 

public class Derived:Base 
{ 
    public override int Add(int a,int b) 
    { 
     return a+b; 
    } 

    public int Add(float a,float b) 
    { 
     return (Int32)(a + b); 
    } 
} 

如果我创建派生类的实例,并调用添加与它为什么调用带有浮动参数的Add方法int类型的参数

Derived obj =new Derived() 
obj.Add(3,5) 

// why this is calling 
Add(float a,float b) 

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

+1

你怎么知道3和5是int?尝试指定他们的类型,看看会发生什么。 –

+0

你怎么知道它是? –

+0

你能编译这个吗?你可能会得到一些类似float的类型转换错误吗? – Anuraj

回答

15

这是设计。 C#语言规范状态的第7.5.3节:

例如,用于集合的方法调用的候选不包括标记方法倍率(§7.4),并在一个基类的方法都没有候选如果任何方法在派生类中是适用的(第7.6.5.1节)。

换句话说,因为你Derived类具有非重写Add方法,在Base类(和Derived其重写版本)的Add方法不再是超负荷分辨率候选。

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

Eric Lippert在this blog post中讨论了此设计的一些原因。

+0

+1好答案。证明,解释和进一步阅读的链接。 – Matt

+0

有没有办法在保持原始方法可见的同时为虚拟方法添加重载? – supercat