Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么can`s=>;x、 Append(s)`可以作为操作传递<;字符串>;但是'x.Append'可以';T_C#_.net_Lambda - Fatal编程技术网

C# 为什么can`s=>;x、 Append(s)`可以作为操作传递<;字符串>;但是'x.Append'可以';T

C# 为什么can`s=>;x、 Append(s)`可以作为操作传递<;字符串>;但是'x.Append'可以';T,c#,.net,lambda,C#,.net,Lambda,当我试图将StringBuilder的Append方法传递给执行操作的函数时,我注意到了一些奇怪的情况 但是,这会产生编译错误,因为Append方法与所需的签名不匹配(它返回对StringBuilder的引用,而不是像我的方法所希望的那样无效): “System.Text.StringBuilder System.Text.StringBuilder.Append(string)”的返回类型错误 不假思索,我将代码更改为: var output = new StringBuilder(); Do

当我试图将
StringBuilder
Append
方法传递给执行
操作的函数时,我注意到了一些奇怪的情况

但是,这会产生编译错误,因为
Append
方法与所需的签名不匹配(它返回对
StringBuilder
的引用,而不是像我的方法所希望的那样无效):

“System.Text.StringBuilder System.Text.StringBuilder.Append(string)”的返回类型错误

不假思索,我将代码更改为:

var output = new StringBuilder();
DoStuff(s => output.Append(s));
这很好

然后我感到困惑;意识到
s=>output.Append
也应该返回
StringBuilder
,它们不一样吗

那么,为什么会这样呢?为什么
s=>output.Append(s)
可以默默地丢弃返回值,而
output.Append(s)
却不能?

s=>output.Append(s)
创建一个新的lambda表达式,该表达式(从上下文)被推断为返回类型为
void

因此,表达式体的值被忽略。
这被编译成一个单独的方法,该方法调用
Append()
,并返回void(与委托完全匹配)

相反,当您尝试将方法组转换为委托时,转换必须完全匹配

规范(§6.5)规定:

具体而言,匿名函数F与提供的委托类型D兼容:

  • 如果F的主体是一个表达式,并且D具有无效的返回类型,或者F是异步的,并且D具有返回类型任务,那么当F的每个参数都给定了D中相应参数的类型时,F的主体是一个有效的表达式(wrt§7),它将被允许作为语句表达式(§8.6)

我很困惑,如何不使用多行lambda将其转换为:
s=>{return output.Append(s);}
。我认为他们是平等的。@gunr2171:不;它被推断为不返回任何内容/@gunr2171 C#中的Lambda表达式总是根据其用法进行推断
s=>output.Append本身没有意义。它只有在编译器可以推断类型的地方才有意义。这是因为lambda表达式也可以与表达式树一起使用,例如
expression expr=s=>output.Append
。这就推断lambda是一种甚至不是委托的类型是一个编译错误。编译器无法推断表达式类型,因此使用
var
是不正确的。@DannyTuppeny:请参阅我的编辑以获取相关的规范引用。请注意
var output = new StringBuilder();
DoStuff(output.Append);
var output = new StringBuilder();
DoStuff(s => output.Append(s));