dea*_*ull 6 c# ambiguity overload-resolution
我在调用具有不同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)
{
}
}
Run Code Online (Sandbox Code Playgroud)
当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))
Run Code Online (Sandbox Code Playgroud)
这样一情况下,将过载解析过程中不需要隐式转换(如铸造后Action<T>类型将完全匹配),另将不得不被转换(Action<long>至Action<decimal>),以及上面提到的部分指出:
[...]
如果S是T1,则C1是更好的转换.
如果S是T2,则C2是更好的转换.
[...]