【问题标题】:Why does "Func<bool> test = value ? F: F" not compile?为什么“Func<bool> test = value ? F: F”无法编译?
【发布时间】:2011-05-16 10:01:22
【问题描述】:

我见过类似的问题,但它们涉及不同的类型,所以我认为这是一个新问题。

考虑以下代码:

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 必须属于同一类型,因为它们是相同的实体,Func。那为什么不编译呢?

【问题讨论】:

  • 我不知道,但你能解释一下如何在表达式Func 中编写一个返回类型为 void 的方法名吗??
  • 抱歉,为了简化原始代码中的代码,我错误地删除了返回类型。我现在已经修好了!

标签: c#


【解决方案1】:

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

但是,问题本质上是相同的。 IE。 F 可以有任意数量的匹配委托声明,并且由于两个相同的委托声明之间没有隐式转换,F 的类型不能转换为 Func&lt;bool&gt;

同样,如果你声明

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]。

【讨论】:

  • 但是即使您明确指定测试变量的类型为:public delegate void FuncDelegate();这条线仍然不起作用: FuncDelegate funcDelegate = value ?功能:功能;为什么?
  • 我已经修复了我的示例以匹配我在原始代码中的内容;我第一次在这里发布时过于简化了。
  • 我更改了我的代码,以便不再分配给隐式类型变量。
  • 谢谢布赖恩 - 我认为我的问题在于认为方法本质上具有类型 - 但只有委托才具有。
  • @BashirMagomedov - 在决定是否可以确定所需的签名时,编译器似乎不会查看条件表达式之外的内容。
【解决方案2】:
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

【讨论】:

  • 有趣,但为什么value ? (Action)f : g;value ? f : (Action)g; 都编译?
  • @MateenUlhaq - 因为当您将所需的 签名 (Action) 提供给任何一半时,编译器就知道所需的目标是什么。然后它可以确定另一半是否可以转换为相同的签名。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-12
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多