gpt4 book ai didi

c# - 为什么 `s => x.Append(s)` 可以作为 Action 传递但 `x.Append` 不能?

转载 作者:可可西里 更新时间:2023-11-01 03:08:37 24 4
gpt4 key购买 nike

我在尝试传递 StringBuilder 时注意到一些奇怪的事情的 Append使用 Action<string> 的函数的方法.

public void DoStuff(Action<string> handler)
{
// Do stuff, call handler("data");
}

出于测试目的,我只想将数据写入 StringBuilder ,所以我试着这样调用它:

var output = new StringBuilder();
DoStuff(output.Append);

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

'System.Text.StringBuilder System.Text.StringBuilder.Append(string)' has the wrong return type

想都没想,把代码改成了这样:

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

这编译得很好。

然后我就糊涂了;意识到s => output.Append(s)还应该返回 StringBuilder ,它们不一样吗?

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

最佳答案

s => output.Append(s) 创建一个新的 lambda 表达式,(根据上下文)推断其返回类型为 void
因此,表达式主体的值将被忽略。
这被编译为一个单独的方法,该方法调用 Append() 并返回 void(这与委托(delegate)完全匹配)

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

规范 (§6.5) 说:

Specifically, an anonymous function F is compatible with a delegate type D provided:

  • If the body of F is an expression, and either D has a void return type or F is async and D has the return type Task, then when each parameter of F is given the type of the corresponding parameter in D, the body of F is a valid expression (wrt §7) that would be permitted as a statement-expression (§8.6).

关于c# - 为什么 `s => x.Append(s)` 可以作为 Action<string> 传递但 `x.Append` 不能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24191090/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com