条件语句,泛型委托不必要的演员

the*_*kip 8 c# compiler-construction generics delegates

在设置Action<T>值时,我遇到了条件语句这个非常奇怪的问题.这不是我不知道如何解决这个问题,因为使用普通法很容易解决if.

这是我的问题:

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)
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

这给了我一条消息的编译器错误

"方法组"和"方法组"之间没有隐式转换.

这很奇怪,因为我无法弄清楚为什么这是非法的.

顺便说一句,下面的语法将使这个有效(从编译器的角度来看):

    public void A()
    {
        Action = Foo ? (Action<bool>) B : C;
    }
Run Code Online (Sandbox Code Playgroud)

所以也许你可以阅读这个问题,为什么演员必要?

mqp*_*mqp 2

您混淆了两个相似的概念:

A) 方法组。方法组是一个或多个具有相同名称的 C# 方法。它是主要由编译器使用的抽象;你不能传递方法组。您对方法组所能做的就是调用它或从中创建委托。如果类型签名匹配,您可以从方法组隐式创建委托。

B) 一名代表。你知道什么是代表;它具有特定的类型签名并直接引用方法。除了调用它之外,您还可以传递它并将其视为一流对象。

因此,在第一个示例中,表达式B在一侧返回一个方法组,C在另一侧返回另一个方法组。三元运算符需要在两侧返回相同的类型,但它不知道将两侧转换为什么;将结果分配给 ( Action<bool>) 的变量类型并不决定表达式的类型。所以说是暧昧的。

在第二个示例中,您合法地将方法组强制转换BAction<bool>三元运算符一侧的委托。在尝试消除表达式歧义的过程中,编译器尝试将每一端强制转换为另一端的类型。它可以成功地将方法组转换CAction<bool>,因此它这样做并且表达式是合法的。