简体   繁体   English

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

[英]Delegate can be assigned to either anonymous method or lambda but not to a method

In the following code snippet, 在以下代码段中,

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

delegates of type Action cannot be assigned to a method Work of type Task but weirdly can be assigned to an anonymous method or a lambda of type Task . 型的代表Action不能被分配到一个方法Work类型的Task ,但古怪的可分配给匿名方法或类型的拉姆达Task

In my understanding 在我的理解中

  • Work
  • async () => await Task.Delay(1000)
  • async delegate () { await Task.Delay(1000); }

have the same signature that are not compatible to Action . 具有与Action不兼容的相同签名。 What causes this inconsistency? 是什么导致这种不一致?

Edit: 编辑:

The following lambda and anonymous method 以下lambda和匿名方法

  • async () => await Task.Delay(1000)
  • async delegate () { await Task.Delay(1000); }

can represent both Action or Func<Task> depending on the left hand side of assignment. 可以表示ActionFunc<Task>具体取决于赋值的左侧。 More precisely, 更确切地说,

Converted to Action implicitly, 隐式转换为Action

  • Action a = async () => await Task.Delay(1000)
  • Action b = async delegate () { await Task.Delay(1000); }

Converted to Func<Task> implicitly, 隐式转换为Func<Task>

  • Func<Task> a = async () => await Task.Delay(1000)
  • Func<Task> b = async delegate () { await Task.Delay(1000); }

Is it @JSteward's comment below about? 以下是@ JSteward的评论吗?

First of all, Action is a delegate of return type void : 首先, Action是返回类型void的委托:

public delegate void Action()

and your method has the return type Task . 并且您的方法具有返回类型Task

Secondly, the return type of the anonymous method that is created by the lambda expression is determined by the type of the delegate ( Action ). 其次,由lambda表达式创建的匿名方法的返回类型由委托的类型( Action )决定。 Since the delegate is void , you are creating a void anonymous method. 由于委托是void ,因此您将创建一个void匿名方法。 The return value of the Task.Delay call is discarded. Task.Delay调用的返回值将被丢弃。

Further, your anonymous function from the delegate() expression is not of type Task , as you assume. 此外,您假设, delegate()表达式中的匿名函数不是Task类型。 It is of type void , since it does not have a return statement. 它的类型为void ,因为它没有return语句。 It would not even compile if you added one, since you are trying to assign it to a delegate of type void : 如果你添加一个,它甚至都不会编译,因为你试图将它分配给void类型的委托:

Action c =  async delegate () { return await Task.Delay(1000);  };

gives the error message 给出错误消息

Anonymous function converted to a void returning delegate cannot return a value. 转换为void返回委托的匿名函数无法返回值。

Work is a function with the return type of Task, thats why you can't "put" it into an Action. Work是一个返回类型为Task的函数,这就是为什么你不能把它“放”到Action中。

The only reason for your exemples working, is that the lambda function 你的例子工作的唯一原因是lambda函数

() => Task.Delay(1000);

creates an Action that calls Task.Delay(1000). 创建一个调用Task.Delay(1000)的Action。

void Function()
{
    Task.Delay(1000);
}

And when you create an async lambda 当你创建一个异步lambda

async () => await Task.Delay(1000);

creates an Action that awaits Task.Delay(1000). 创建一个等待Task.Delay(1000)的Action。

async void Function()
{
    await Task.Delay(1000);
}

same applies to the anonymous function. 同样适用于匿名函数。

PS PS

When you await an async function, the Task output is changed to its "type" (in this case void). 当您等待异步函数时,任务输出将更改为其“类型”(在本例中为void)。 Thats why if you await Task.Delay(1000), you get void for the return type. 这就是为什么如果你等待Task.Delay(1000),你得到返回类型的无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM