为什么在C#中我们可以';三元算子中的t求值方法?

为什么在C#中我们可以';三元算子中的t求值方法?,c#,C#,我正在尝试执行下一个代码,但在C#中,这是不允许的。为什么? 在C++中它工作得很好.. void A() { Console.WriteLine("A"); } void B() { Console.WriteLine("B"); } void C() { //getRandomInt return digit from 0 to 99 bool compareResult= getRandomInt(100) < 50; var resul

我正在尝试执行下一个代码,但在C#中,这是不允许的。为什么? 在C++中它工作得很好..

void A()
{
    Console.WriteLine("A");
}

void B()
{
    Console.WriteLine("B");
}

void C()
{
    //getRandomInt return digit from 0 to 99
    bool compareResult= getRandomInt(100) < 50;
    var result = compareResult ? A : B;
    result();
}
void A()
{
控制台。写入线(“A”);
}
无效B()
{
控制台。写入线(“B”);
}
void C()
{
//getRandomInt返回0到99之间的数字
布尔比较结果=getRandomInt(100)<50;
var结果=比较结果?A:B;
结果();
}

错误消息告诉您“方法组和方法组之间没有隐式转换”。在编译器错误的古老传统中,这在任何已知的自然语言中几乎没有任何意义。然而,根据经验,我们了解到它告诉我们需要转换到其他对象,并且我们也从经验中知道,C#对于方法引用的隐式转换很困难,除非引用类型为
Action
Func
。这是一条粗糙的经验法则,我发现当我遇到这些事情时,它能帮助我很快地适应生活。充分正确地理解为什么会是这样是有价值的;请参见下文,了解对此的一些见解

A和B是返回void的非实数方法,所以我尝试转换为
操作
。它被编译了

var result = compareResult ? (Action)A : B;
值得尊敬的埃里克·利珀特(见下文他全部的评论)澄清:

…方法组在C#中没有类型;它们可以转换为某些类型,但没有类型

当我们说“方法”组时,我们的意思是“通过名称引用函数而不调用它”。考虑:

public void A() { }

public int A(int x) => 2 * x;

public void B() { }
有多个
A
。编译器可能能够通过选择一个看起来像B的来解决歧义,如果他们中的任何一个这样做了,但是它没有,根据经验,我有很好的理由解释为什么它不尝试这样做,Eric指出:

简短的说法是:解决这个问题需要付出太多的努力,却收获太少,我们很可能会出错。稍微长一点的版本是:我们决定,在C#中,解析方法组的唯一方法是评估组成员对一组参数的适应性,无论是在调用方法组时以表达式的形式,还是在将方法组转换为委托时以类型的形式。本例中没有可用的参数


但是,当您按照您的建议包含一个cast to(Action)时,突然出现了可用的参数,即一个空的参数列表。现在我们有证据表明开发人员希望选择组中的哪个方法:一个没有参数的方法


<代码>空> <代码>返回或评估到C?C++是完全不同的语言。尽管有类似的语法,但在一个表达式中工作的事实对另一个表达式没有任何意义。@NatPongjardenlarp此表达式的结果不是指向类型为void但不带args的函数的指针?
var result=compareResult?(行动)A:B。您只需要将其转换为动作。C语言的全部思想是不复制C++的坏特性。然而,在这种情况下,问题实际上是错误消息不是很清楚。很抱歉。我本打算修复它,但并没有着手解决它。这很好地说明了错误消息设计的拙劣是如何导致用户困惑的。这里真正的错误是:
?:
运算符的结果必须有一个类型,并且鉴于结果和可选分支的类型,它必须是可能的最佳类型,但方法组在C#中没有类型;它们可以转换为某些类型,但没有类型。错误消息应显示“无法为
?:
运算符确定最佳类型,因为结果和备选分支没有类型;请尝试插入强制转换”。遗憾的是,我一直没能解决这个问题。这可能是我第一次被描述为不可战胜的人。:-)在你的最后一句话中回答你的隐含问题,是的,有很好的理由;简短的说法是:解决这个问题需要付出太多的努力,却收获太少,我们很可能会出错。稍微长一点的版本是:我们决定,在C#中,解析方法组的唯一方法是评估组成员对一组参数的适应性,无论是在调用方法组时以表达式的形式,还是在将方法组转换为委托时以类型的形式。本例中没有可用的参数!但是,当您按照建议将强制转换包括到
(Action)
时,突然出现了可用的参数,即一个空参数列表。现在我们有证据表明开发商愿意在小组中选择哪种方法:一种没有争议的方法。当我在VSTO团队工作时,我曾穿着黑色的掸子、黑色的手套、黑色的裤子和黑色的鞋子,在停车场漆黑的阴影中等待我的拼车来接我,我一定是在我的产品部门经理去她的车的路上意外地吓了一跳,她说:“好吧,你看起来很危险。”。我想她是在开玩笑,但我对此感到很难过;我当然不是故意装出威胁的样子!我只是想躲雨。