可以将委托分配给匿名方法或lambda,但不分配给方法

Mon*_*mer 2 c# asynchronous async-await

在以下代码段中,

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);  };
    }
}
Run Code Online (Sandbox Code Playgroud)

类型的委托Action不能分配给Work类型的方法,Task但奇怪的是可以分配给匿名方法或类型的lambda Task.

在我的理解中

  • 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); }

可以表示两者ActionFunc<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的评论吗?

Adr*_*ian 5

首先,Action是一个返回类型的委托void:

public delegate void Action()
Run Code Online (Sandbox Code Playgroud)

并且您的方法具有返回类型Task.

其次,lambda表达式创建的匿名方法的返回类型由委托(Action)的类型决定.由于委托是void,您正在创建一个void匿名方法.Task.Delay呼叫的返回值被丢弃.

此外,您所假设的delegate()表达式中的匿名函数不是类型Task.它是类型的void,因为它没有return声明.如果你添加一个,它甚至都不会编译,因为你试图将它分配给一个类型的委托void:

Action c =  async delegate () { return await Task.Delay(1000);  };
Run Code Online (Sandbox Code Playgroud)

给出错误消息

转换为void返回委托的匿名函数无法返回值.