采用以下代码:
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<TBaseClassB>(TBaseClassB)
方法重载而不是 Operations.Method(BaseClassA)
给予时
DerivedClassA1
类型的参数,这与我的预期相反。
为什么是这样?难道我做错了什么?是否有替代/正确的实现方式
我想要的是调用 Method(BaseClassA)
方法重载。
请注意,示例代码是我正在使用的一些真实代码的简化等价物 在。如果这个例子看起来做作,我们深表歉意。
最佳答案
重载决议不考虑泛型约束,因为这些约束实际上并不是方法签名的一部分(您不能在只有泛型约束不同的同一类中创建相同的方法)。解析算法首先选择最佳候选者,然后才检查它是否验证了约束。
在您的情况下,如果您忽略 where TBaseClassB : BaseClassB, new()
约束,则通用重载是更好的选择,因为如果 TBaseClassB
是 DerivedClassA1
,它比非泛型更接近匹配(Method(DerivedClassA1)
比 Method(BaseClassA)
更接近)。但是随后,它检查约束并发现 DerivedClassA1
没有继承 BaseClassB
,这导致了错误。
换句话说,在检查泛型约束之前,已经消除了非泛型重载。
关于c# - 当我期望它选择非泛型方法时,方法重载选择了泛型方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21603034/