c#通用重载方法调度模糊

Seb*_*ian 7 c# generics methods overloading dispatch

我刚刚遇到一个方法调度模糊的情况,并想知道是否有人可以解释编译器(.NET 4.0.30319)选择什么重载调用的基础

interface IfaceA
{

}

interface IfaceB<T>
{
    void Add(IfaceA a);
    T Add(T t);
}

class ConcreteA : IfaceA
{

}

class abstract BaseClassB<T> : IfaceB<T>
{
    public virtual T Add(T t) { ... }
    public virtual void Add(IfaceA a) { ... }
}

class ConcreteB : BaseClassB<IfaceA>
{
    // does not override one of the relevant methods
}

void code()  
{
    var concreteB = new ConcreteB();

    // it will call void Add(IfaceA a)
    concreteB.Add(new ConcreteA());
}
Run Code Online (Sandbox Code Playgroud)

在任何情况下,为什么编译器不会警告我,甚至为什么编译?非常感谢您的任何答案.

Jon*_*eet 2

它遵循C# 4 规范第 7.5.3.2 节(“更好的函数成员”)中的规则。

\n\n

首先(嗯,在看到这两种方法都适用之后)我们需要检查从参数类型到参数类型的转换。在本例中,它相当简单,因为只有一个参数。参数类型到参数类型的转换都不是“更好”,因为两者都是从 转换ConcreteAIfaceA。因此,它转向下一组标准,包括:

\n\n
\n

否则,如果 MP 比 MQ 具有更具体的参数类型,则 MP 比 MQ 更好。令 {R1, R2, \xe2\x80\xa6, RN}\n 和 {S1, S2, \xe2\x80\xa6, SN} 表示 MP 和 MQ 的未实例化和未扩展的参数类型。MP\xe2\x80\x99s\n 参数类型比\n MQ\xe2\x80\x99s 更具体,如果对于每个参数,RX 不\n 不比 SX 更具体,并且,对于至少一个参数, RX 比 SX 更具体:比 SX 更具体:

\n\n
    \n
  • 类型参数不如非类型参数具体。
  • \n
  • ...
  • \n
\n
\n\n

因此,即使转换IfaceA同样好,直接使用(而不是通过委托)的重载被认为“更好”,因为 type 的参数IfaceA比 type 的参数更具体T

\n\n

没有办法让编译器警告这种行为 - 这只是正常的重载解析。

\n