将任意操作传递给同一方法

时间:2013-09-21 09:05:56

标签: c# .net ambiguity

为什么以下呼叫含糊不清:

public class Foo
{
    public void Bar<T> (Action<T> simple);
    public void Bar<T1, T2> (Action<T1, T2> complex);
}

...

public class Test
{
    public static void MyComplex (string a, string b) { ... }
}

...

foo.Bar(Test.MyComplex);

编译器是否应该清楚调用Bar<T1,T2>()方法?

2 个答案:

答案 0 :(得分:1)

如果删除此方法public void Bar<T> (Action<T> simple);,您的代码将无法编译,因为您遇到此异常:

  

方法'Foo.Bar(System.Action)'的类型参数   无法从使用中推断出来。尝试指定类型参数   明确。

不幸的是,编译器无法从此方法获取类型,您应该将此代码编写为call方法:

new Foo().Bar(new Action<string, string>(Test.MyComplex));

答案 1 :(得分:0)

编译器正在尝试推断Bar的泛型参数类型,但要做到这一点,它需要知道所有参数类型。您拥有的参数(Test.MyComplex)实际上是方法组,而不是委托,因此编译器也需要将转换插入到兼容的委托类型中。但它不能,因为它不知道要使用什么委托类型,因为它需要兼容的方法的类型推断还没有完成。有一个鸡与蛋问题,编译器放弃说这个电话是模棱两可的。 Eric Lippert在评论中指出了一个非常相似的question,在这种简单的情况下,它可以解决,但代价是使重载决策规则复杂化。

不幸的是,您需要做一些能为编译器提供更多信息的东西:

foo.Bar<string, string>(Test.MyComplex);

Action<string, string> action = Test.MyComplex;
foo.Bar(action);