为什么“Func test = value? F:F“不编译?

我已经看到了类似的问题,但它们涉及不同类型,所以我认为这是一个新问题。

请考虑以下代码:

public void Test(bool value) { // The following line provokes a compiler error: // "Type of conditional expression cannot be determined because there is // no implicit conversion between 'method group' and 'method group". Func test = value ? F : F; } public bool F() { return false; } 

现在,根据C#3.0标准,

?:运算符的第二个和第三个操作数控制条件表达式的类型。 设X和Y是第二个和第三个操作数的类型。 然后,

如果X和Y是相同的类型,则这是条件的类型否则,如果从X到Y存在隐式转换(第6.1节),而不是从Y到X,则Y是条件表达式的类型。 否则,如果从Y到X存在隐式转换(第6.1节),而不是从X到Y,则X是条件表达式的类型。 否则,不能确定表达式类型,并发生编译时错误。

在我看来,在我的示例代码中,X和Y必须是相同的类型,因为它们是同一个实体Func 。 那为什么不编译呢?

问题发生了重大变化,所以我原来的答案现在有点过时了。

但是,问题基本相同。 即, F可以有任意数量的匹配委托声明,并且由于两个相同的委托声明之间没有隐式转换,因此F的类型无法转换为Func

同样,如果你宣布

 private delegate void X(); private delegate void Y(); private static void Foo() {} 

你做不到

 X x = Foo; Y y = x; 

原始答案:

它不起作用,因为无法将方法组分配给隐式类型变量。

var test = Func; 也不起作用。

原因是Func可能有任意数量的委托类型。 例如, Func匹配这两个声明(除了Action

 private delegate void X(); private delegate void Y(); 

要将隐式类型变量与方法组一起使用,您需要通过强制转换来消除歧义。


请参阅archil的答案 ,了解解决此问题的一种方法的具体示例。 也就是说,他显示了更正后的代码可能是什么样子[假设您希望匹配的代表是Action ]。

 var test = value ? (Action)Func: (Action)Func; 

实际上,方法的type由委托匹配表示。 我用来转换方法的System.Action是签名返回void并且不带参数的委托 – 它匹配你的Func()方法。 现在你的test将知道它是System.Action的类型。 代表就像方法的接口。 看看http://msdn.microsoft.com/en-us/library/ms173171(v=vs.80).aspx