我只是遇到了一种方法分配模棱两可的情况,想知道是否有人可以解释编译器(.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());
}

无论如何,为什么编译器不警告我,甚至为什么不编译呢?
非常感谢您提供任何答案。

最佳答案

它遵循C# 4 specification(“更好的功能成员”)第7.5.3.2节中的规则。

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



因此,即使转换同样出色,直接使用IfaceA(而不是通过委托(delegate))的重载也被视为“更好”,因为IfaceA类型的参数比T类型的参数更具体。

没有办法让编译器就此行为发出警告-这只是正常的重载解决方案。

10-06 05:53