C# 带有操作的方法调用不明确<;T>;参数过载
在使用不同的C# 带有操作的方法调用不明确<;T>;参数过载,c#,ambiguity,overload-resolution,C#,Ambiguity,Overload Resolution,在使用不同的Action变体调用重载方法时,我遇到了一些意外的编译器行为 假设我有这个类Test,我正在CallTest构造函数中创建它的实例 public class Test { public Test(Action<long> arg) { } public Test(Action<decimal> arg) { } } public class CallTest { public CallTest()
Action
变体调用重载方法时,我遇到了一些意外的编译器行为
假设我有这个类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)
{
}
}
公共类测试
{
公共测试(动作参数)
{
}
公共测试(动作参数)
{
}
}
公共类调用测试
{
公共CallTest()
{
测试t=新测试(TestDecimal);
}
公共void TestDecimal(十进制参数)
{
}
公共void TestLong(long arg)
{
}
}
使用TestDecimal
或TestLong
作为参数调用Test
构造函数时,我收到以下错误:
以下方法或属性之间的调用不明确:“Test(System.Action)
”和“Test(System.Action)
”
我猜在
long
和decimal
之间有一些隐含的转换,但是有人知道我做错了什么吗?有什么解决办法吗?这是由于long和decimal之间存在隐式转换
下面是C#()中的隐式类型转换表:阅读有关类型转换的更多信息。有一个解决方法:
Test t = new Test(new Action<decimal>(TestDecimal));
Test t=新测试(新操作(TestDecimal));
当您将TestDecimal
或TestLong
作为参数传递时,实际上您传递的是一个方法组(毕竟,可能有多个TestDecimal
方法-它可能已被重载)。因此,在这两种情况下都会发生隐式转换——从方法组到特定委托类型。因此,这两种方法都适用()。重载解析算法试图从适用的候选对象中找到最佳候选对象。但是,匹配参数列表时比较转换的规则规定,如果两个候选项都发生隐式转换,则两者都不是更好的:
:
[……]
否则,两种转换都不好
这就是为什么在你的案例中存在歧义
解决方法当然是首先显式转换参数:
new Test(new Action<decimal>(TestDecimal))
新测试(新操作(TestDecimal))
这样一来,对于一种情况,在重载解析期间将不需要隐式转换(因为在强制转换之后,操作
类型将完全匹配),而另一种情况将必须转换(操作
到操作
),并且上述部分说明:
[……]
如果S是T1,则C1是更好的转换
如果S是T2,则C2是更好的转换
[……]