使用不同的 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
作为参数,我收到以下错误:
The call is ambiguous between the following methods or properties: '
Test(System.Action<long>)
' and 'Test(System.Action<decimal>)
'
我的猜测是在 long
之间进行了一些隐式转换和 decimal
,但是有没有人知道我做错了什么?有什么解决方法吗?
最佳答案
当你通过 TestDecimal
或 TestLong
作为参数,您实际上传递了一个方法组(毕竟,可能有不止一个 TestDecimal
方法 - 它可能已经过载)。因此在这两种情况下都会发生隐式转换 - 从方法组到特定的委托(delegate)类型。因此,这两种方法都是适用的候选者 ( Section 7.4.2 )。从适用的候选者中,重载解析算法试图找到最佳候选者。但是,匹配参数列表时比较转换的规则表明,如果两个候选者都发生隐式转换,则两者都不是更好:
[...]
Otherwise, neither conversion is better.
这就是为什么您的情况存在歧义。
解决方法当然是首先显式转换参数:
new Test(new Action<decimal>(TestDecimal))
对于一种情况,这种方式在重载解析期间不需要隐式转换(因为转换后 Action<T>
类型将完全匹配),而另一种情况必须转换( Action<long>
到 Action<decimal>
) ,并且上面提到的部分指出:
[...]
If S is T1, C1 is the better conversion.
If S is T2, C2 is the better conversion.
[...]
关于c# - 带有 Action<T> 参数重载的模糊方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24011887/