在以下代码段中,
class Program
{
static async Task Work()
{
await Task.Delay(1000);
}
static async Task Main()
{
// Action a = Work;
Action b = async () => await Task.Delay(1000);
Action c = async delegate () { await Task.Delay(1000); };
}
}
类型Action
的委托不能分配给Work
类型的方法Task
,但奇怪的是可以分配给匿名方法或Task
类型的lambda。 / p>
根据我的理解
Work
async () => await Task.Delay(1000)
async delegate () { await Task.Delay(1000); }
具有与Action
不兼容的相同签名。造成这种不一致的原因是什么?
以下lambda和匿名方法
async () => await Task.Delay(1000)
async delegate () { await Task.Delay(1000); }
可以代表Action
或Func<Task>
,具体取决于作业的左侧。更准确地说,
隐式转换为Action
,
Action a = async () => await Task.Delay(1000)
Action b = async delegate () { await Task.Delay(1000); }
隐式转换为Func<Task>
,
Func<Task> a = async () => await Task.Delay(1000)
Func<Task> b = async delegate () { await Task.Delay(1000); }
下面是@ JSteward的评论吗?
答案 0 :(得分:5)
首先,Action
是返回类型void
的代理:
public delegate void Action()
,您的方法的返回类型为Task
。
其次,lambda表达式创建的匿名方法的返回类型由委托的类型(Action
)决定。由于委托是void
,因此您正在创建void
匿名方法。 Task.Delay
调用的返回值将被丢弃。
此外,您假设,delegate()
表达式中的匿名函数不是Task
类型。它的类型为void
,因为它没有return
语句。如果你添加一个,它甚至都不会编译,因为你试图将它分配给void
类型的委托:
Action c = async delegate () { return await Task.Delay(1000); };
给出错误消息
转换为void返回委托的匿名函数无法返回值。
答案 1 :(得分:2)
Work是一个返回类型为Task的函数,这就是为什么你不能把它“放”到Action中。
你的例子工作的唯一原因是lambda函数
() => Task.Delay(1000);
创建一个调用Task.Delay(1000)的Action。
void Function()
{
Task.Delay(1000);
}
当你创建一个异步lambda
时async () => await Task.Delay(1000);
创建一个等待Task.Delay(1000)的Action。
async void Function()
{
await Task.Delay(1000);
}
同样适用于匿名函数。
P.S。
等待异步函数时,Task输出更改为“type”(在本例中为void)。这就是为什么如果等待Task.Delay(1000),你的返回类型就会失效。