在调用具有不同Action<T>
变体的重载方法时,我遇到了一些意外的编译器行为。
假设我有此类,Test
并且正在CallTest
构造函数中创建其实例。
public class Test
{
public Test(Action<long> arg)
{
}
public Test(Action<decimal> arg)
{
}
}
public class CallTest
{
public CallTest()
{
Test t = new Test(TestDecimal);
}
public void TestDecimal(decimal arg)
{
}
public void TestLong(long arg)
{
}
}
当Test
使用TestDecimal
或TestLong
作为参数调用构造函数时,我收到以下错误:
下列方法或属性之间的调用不明确:“
Test(System.Action<long>)
”和“Test(System.Action<decimal>)
”
我的猜测是在long
和之间进行了一些隐式转换decimal
,但是还有谁知道我可能做错了什么吗?有什么解决方法吗?
当您通过TestDecimal
或TestLong
作为参数传递时,实际上是在传递方法组(毕竟,可能有多个TestDecimal
方法-它可能已被重载)。因此,在两种情况下都发生隐式转换-从方法组到特定的委托类型。因此,这两种方法都是适用的候选方法(第7.4.2节)。从适用的候选对象中,过载解决算法会尝试找到最佳候选对象。但是,在匹配参数列表时比较转换的规则表明,如果对于这两个候选者都进行隐式转换,则它们都不是更好的:
[...]
否则,两种转换都不会更好。
这就是为什么在您的情况下存在歧义。
解决方法当然是首先显式转换参数:
new Test(new Action<decimal>(TestDecimal))
对于一种情况,这种方法在重载解析期间无需进行隐式转换(因为在强制转换Action<T>
类型完全匹配之后),而另一种则必须转换(Action<long>
为Action<decimal>
),并且上述部分指出:
[...]
如果S是T1,则C1是更好的转换。
如果S是T2,则C2是更好的转换。
[...]
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句