为什么"Func <bool> test = value?F:F"无法编译?

Mat*_*son 20 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;
}
Run Code Online (Sandbox Code Playgroud)

现在,根据C#3.0标准,

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

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

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

Bri*_*sen 12

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

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

同样,如果你宣布

private delegate void X();
private delegate void Y();
private static void Foo() {}
Run Code Online (Sandbox Code Playgroud)

你做不到

X x = Foo;
Y y = x;
Run Code Online (Sandbox Code Playgroud)

原始答案:

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

var test = Func; 也不起作用.

原因是可以有任意数量的委托类型Func.例如,Func匹配这两个声明(除此之外Action)

private delegate void X();
private delegate void Y();
Run Code Online (Sandbox Code Playgroud)

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


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


arc*_*hil 8

var test = value ? (Action)Func: (Action)Func;
Run Code Online (Sandbox Code Playgroud)

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