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

use*_*219 4 c# lambda delegates anonymous-function

我有一个一般性的问题:在下面的C#代码中tFour无法创建线程,并且编译器向我显示以下错误:“将匿名函数转换为void返回的委托无法返回值

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DelegatesAndLambda
{
    class Program
    {
        public static int ThrowNum(object a)
        {
            Console.WriteLine(a);
            return 2 * (int)a;
        }
        static void Main(string[] args)
        {
            Func<int> newF = delegate () { int x = ThrowNum(2); return x; };
            Thread tOne = new Thread( delegate () { int x = ThrowNum(2); });
            Thread tTwo= new Thread(()=> ThrowNum(2));
            Thread tThree = new Thread(() => newF());
            Thread tFour = new Thread(delegate () { int x = ThrowNum(2); return x;});
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,线程tOnetTwo并且tThree都没有错误产生。那么,为什么lambda表达式允许传递带有返回(非无效)值和多个参数(ThrowNum(2), newF())的方法delegate () { int x = ThrowNum(2); return x;}委托,而不能传递使用委托关键字定义的带有返回值()的匿名方法呢?我以为在两种情况下我们都处理匿名方法?我确实知道Thread 仅接受两种类型的签名:void DoSomething()和void,DoSomething(object o) 但是初始化tTwotFour使用same(?)匿名方法之间的主要区别是什么?我一直试图寻找答案,但没有成功。谢谢

Jon*_*eet 5

仅表达式主体的lambda表达式具有结果并不意味着它已被使用。只要lambda表达式void的主体是有效的语句表达式,它就可以将返回结果的lambda表达式转换为具有返回类型的委托。这是一个简单的例子:

using System;

class Test
{
    static int Method() => 5;

    static void Main()
    {
        Action action = () => Method();
    }
}
Run Code Online (Sandbox Code Playgroud)

很好,因为Method()它是有效的语句表达式。它只是调用方法,而忽略结果。这会不会是有效的,因为1 + 1不是一个有效的语句表达:

// error CS0201: Only assignment, call, increment, decrement,
//               await, and new object expressions can be used as a statement
Action action = () => 1 + 2;
Run Code Online (Sandbox Code Playgroud)

不存在表达式绑定的匿名方法,因此事情变得简单了一些:您无法从匿名方法返回值并将该匿名方法转换为具有void返回类型的委托类型。

C#5 ECMA标准的相关部分是11.7.1:

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

  • ...
  • 如果F的主体是表达式,并且D的返回类型为void或F是异步的并且D的返回类型为Task,则当给F的每个参数赋予D中相应参数的类型时,F的主体是一个有效的表达式(wrt§12),可以将其用作语句表达式(第13.7节)。

  • 好吧,您可以免费获得标准,并根据需要阅读尽可能多的内容:) https://www.ecma-international.org/publications/standards/Ecma-334.htm (2认同)