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

C# 无法确定条件表达式的类型(Func),c#,generics,delegates,C#,Generics,Delegates,将方法分配给Func-类型时,我得到编译错误无法确定条件表达式的类型,因为“方法组”和“方法组”之间没有隐式转换 这仅在时发生:操作员。守则: 公共类测试 { 公共静态字符串1(int值) { 数值+=1; 返回值.ToString(); } 公共静态字符串2(int值) { 数值+=2; 返回值.ToString(); } 公共无效测试(bool) { //这很有效 Func actionWorks; 如果(哪个)actionWorks=1;否则actionWorks=2; //“一:二”部分

将方法分配给
Func
-类型时,我得到编译错误
无法确定条件表达式的类型,因为“方法组”和“方法组”之间没有隐式转换

这仅在
时发生:操作员。守则:

公共类测试
{
公共静态字符串1(int值)
{
数值+=1;
返回值.ToString();
}
公共静态字符串2(int值)
{
数值+=2;
返回值.ToString();
}
公共无效测试(bool)
{
//这很有效
Func actionWorks;
如果(哪个)actionWorks=1;否则actionWorks=2;
//“一:二”部分的编译错误
Func action=哪个?一:二;
}
}

我发现了协方差和逆变,但我不认为这适用于上述情况。为什么这不起作用?

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

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

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

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

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

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

Func<int, string> action = which ? new Func<int, string>(One) : new Func<int, string>(Two);
Func action=哪个?新职能(一):新职能(二);
乔恩的解决方案有效

var action = which ? (Func<int, string>)One : Two;
var action=哪个?(Func)一:二;
另一种选择是自己创建一个新的匿名委托。这在语义上有点不同,但我认为这也很有用

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

我觉得这首歌更优雅,虽然没有那么短。

就是这样。类型完全相同(或者在c语言中,一个方法的类型不同于两个方法,因为它是两个不同的方法?)@doekman:
One
Two
的类型是“方法组”——可能有多个重载,编译器不会试图将它们缩小到“合理”的范围选择仅仅因为它们显示为
?:
的操作数。好的,“方法组”就是这个意思。我想我现在了解了错误的情况。谢谢大家。您的答案更优雅,但每次调用
操作时都会决定
if
结果,而在@Sven answer上,if结果只会决定一次。@AkiraYamamoto您说得对。虽然在这种情况下,它只是一个变量检查,并且大多数情况下不会成为性能问题,但它的优雅性受到逻辑低效/无意义的影响。