无法确定条件表达式的类型(Func)

时间:2011-06-10 15:11:38

标签: c# generics delegates

将方法分配给Func - 类型时,我收到编译错误Type of conditional expression cannot be determined because there is no implicit conversion between 'method group' and 'method group'

这只发生在? :运算符上。代码:

public class Test
{
    public static string One(int value)
    {
        value += 1;
        return value.ToString();
    }
    public static string Two(int value)
    {
        value += 2;
        return value.ToString();
    }
    public void Testing(bool which)
    {
        // This works
        Func<int, string> actionWorks;
        if (which) actionWorks = One; else actionWorks = Two;

        // Compilation error on the part "One : Two"
        Func<int, string> action = which ? One : Two;
    }
}

我发现some information关于共同和逆变,但我不知道这是如何适用于上述情况的。为什么这不起作用?

3 个答案:

答案 0 :(得分:29)

您需要明确提供至少一个方法组的签名。但是,在执行此操作后,编译器将允许您将action声明为隐式类型的本地:

var action = which ? (Func<int, string>)One : Two;

发生这种情况的原因是operator ?:的返回类型不是基于您尝试将其分配给的,而是基于两个表达式的类型推断出来的。如果类型相同或者它们之间存在隐式转换,则编译器会成功推导出返回类型;否则,它抱怨没有转换。

答案 1 :(得分:6)

当您直接将一个函数分配给委托时,如果该函数与签名匹配,编译器会将该函数转换为所需的委托类型。

但是,当您使用?:运算符时,就编译器而言,您不是直接分配给委托,因此它不知道对于One和Two使用什么类型,所以它认为?:运算符中使用的两种类型不匹配。

唯一的解决方法是明确转换:

Func<int, string> action = which ? new Func<int, string>(One) : new Func<int, string>(Two);

答案 2 :(得分:2)

Jon的解决方案正常运作

var action = which ? (Func<int, string>)One : Two;

另一种方法是自己创建一个新的匿名委托。这在语义上是不同的,但我认为这也很有用。

Func<int, string> action = x => which ? One(x) : Two(x);

我发现这个'更优雅,但不是那么短......