为什么“Func <bool> test = value?F:F”不能编译?</bool>

时间:2011-05-16 10:01:22

标签: c#

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

请考虑以下代码:

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<bool> test = value ? F : F;
}

public bool F()
{
    return false;
}

现在,根据C#3.0标准,

  

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

     

如果X和Y是相同的类型,那么   这是条件的类型   否则,如果是隐式转换   (§6.1)从X到Y存在,但不存在   从Y到X,然后是Y的类型   条件表达式。否则,如果   存在隐式转换(第6.1节)   从Y到X,但不是从X到Y,那么   X是条件的类型   表达。否则,没有表达   类型可以确定,和   发生编译时错误。

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

2 个答案:

答案 0 :(得分:12)

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

然而,问题基本相同。即F可以有任意数量的匹配委托声明,因为两个相同的委托声明之间没有隐式转换,F的类型无法转换为Func<bool>

同样,如果您声明

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's answer。也就是说,他显示了更正的代码可能是什么样子[假设您希望匹配的代表是Action]。

答案 1 :(得分:8)

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