【问题标题】:Method overload selecting generic method when I was expecting it to select non-generic method当我期望它选择非泛型方法时,方法重载选择泛型方法
【发布时间】:2014-02-06 12:29:39
【问题描述】:

取以下代码:

class BaseClassA { }
class DerivedClassA1 : BaseClassA { }

class BaseClassB { }
class DerivedClassB1 : BaseClassB { }

static class Operations
{
    public static BaseClassA Method(BaseClassA baseA)
    {
        //...
        return baseA;
    }

    public static TBaseClassB Method<TBaseClassB>(TBaseClassB baseB)
        where TBaseClassB : BaseClassB, new()
    {
        //...
        return baseB;
    }

    class Program
    {
        static void Main(string[] args)
        {
            BaseClassA baseA = new BaseClassA();
            DerivedClassA1 derivedA1 = new DerivedClassA1();
            DerivedClassB1 derivedB1 = new DerivedClassB1();

            baseA = Operations.Method(baseA);
            derivedA1 = Operations.Method(derivedA1); // Compilation error
            derivedB1 = Operations.Method(derivedB1);
        }
    }
}

标记为// Compilation error 的行导致以下错误:

The type 'DerivedClassA1' cannot be used as type parameter
'TBaseClassB' in the generic type or method
'Operations.Method<TBaseClassB>(TBaseClassB)'.
There is no implicit reference conversion from 'DerivedClassA1'
to 'BaseClassB'.

似乎方法重载正在选择 Operations.Method&lt;TBaseClassB&gt;(TBaseClassB) 方法重载而不是Operations.Method(BaseClassA) DerivedClassA1 类型的参数,这与我的预期相反。 为什么是这样?难道我做错了什么?是否有替代/正确的实现方式 我想要的,就是调用Method(BaseClassA)方法重载。

请注意,示例代码是我正在使用的一些实际代码的简化等效项 在。如果示例看起来做作,请致歉。

【问题讨论】:

    标签: c# generics .net-4.0 overloading


    【解决方案1】:

    重载解析不考虑泛型约束,因为这些约束实际上并不是方法签名的一部分(您不能在只有泛型约束不同的同一个类中创建相同的方法)。解析算法首先选择最佳候选者,然后才检查它是否验证了约束。

    在您的情况下,如果您忽略where TBaseClassB : BaseClassB, new() 约束,则泛型重载是更好的候选者,因为如果TBaseClassB 是DerivedClassA1,则它比非泛型更接近(Method(DerivedClassA1) 更接近比Method(BaseClassA))。但随后,它检查约束并发现DerivedClassA1 没有继承BaseClassB,从而导致错误。

    换句话说,在检查泛型约束之前,非泛型重载已经被消除。

    【讨论】:

      猜你喜欢
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-09
      • 1970-01-01
      相关资源
      最近更新 更多