public class Test
{
public bool Foo { get; set; }
public Action<bool> Action { get; set; }
public void A()
{
Action = Foo ? B : C;//Gives compiler error
}
public void B(bool value)
{
}
public void C(bool value)
{
}
}
在这里是我的问题:
public void A()
{
Action = Foo ? (Action<bool>) B : C;
}
这给我一个编译器错误,并带有消息
“方法组”和“方法组”之间没有隐含的转换。
这很奇怪,因为我不知道为什么这是非法的。通过方式,以下语法将使此有效(从编译器的角度来看):
B
因此,也许您可以阅读这个问题,因为为什么是必要的?
您将两个类似的概念混为一谈:
a)方法组。 方法组是具有相同名称的一个或多个C#方法。 这是编译器主要使用的抽象;您无法传递方法组。 您可以使用方法组来调用它或从中创建一个代表。 如果类型签名匹配,则可以隐式从方法组创建委托。
B)代表。 你知道代表是什么。它具有特定类型的签名,并直接指定方法。 除了调用它之外,您还可以将其传递给它并将其视为一流的对象。
中,在第一个示例中,您的表达式返回一个方法组Action<bool>
在第二个示例中,您合法地将方法组投入到三元操作员的一侧的
B
委托。 在试图消除表达式的过程中,编译器试图将每一侧投入到另一侧的类型上。 它可以成功地将方法组划分为
Action<bool>
,因此它确实如此,并且表达方式是合法的。
由于实际上不是委托。它们是方法组,可以暗示转换为代表(尤其是
C
),但这不是同一件事。有条件表达式的类型必须在两个分支上保持一致,并且由于当前是方法组(未键入),编译器无法弄清楚该类型应该是什么。正如它告诉您的那样,它们之间没有隐含的转换。 很好,它(或至少是doesnot
)看着分配操作员的另一侧,说“哦,应该是
Action<bool>
”。
当您添加铸件时,左分支表达式的类型变为
B
整个表达是
C
。
我会告诉我,我的推理有点不正确,但是无论如何我都会尝试一下,并希望他的更正:-)
A方法组,例如,没有类型,它不是对象(
Action<bool>
不会编译)。
它可以很容易地转换为一种类型,这就是为什么存在隐式演员的原因。
样本:
B
如您所见,在链接的问题中可以看到,三元表达式试图找到表达式匹配的两个部分的返回类型。它不知道以后转换为C
应该发生。因为方法组本身没有类型,所以它们之间没有转换,并且不能将其转换为Action<bool>
,因此,编译器几乎抱怨。
通过将三元表达式的任何部分施放到Action<bool>
,您告诉编译器,返回类型应该是该类型,并且它检查了三元表达式的另一部分是否支持该类型的隐式铸件。因为是这种情况,所以代码将编译。