Lambda表达式中包含的变量未定义

时间:2016-12-20 11:24:33

标签: c# lambda

请参阅下面的代码摘录,我在此处找到:https://msdn.microsoft.com/en-us/library/dd537612(v=vs.110).aspx

static void SimpleContinuation()
      {
         string path = @"C:\users\public\TPLTestFolder\";
         try
         {
            var firstTask = new Task(() => CopyDataIntoTempFolder(path));
            var secondTask = firstTask.ContinueWith((t) => CreateSummaryFile(path));
            firstTask.Start();
         }
         catch (AggregateException e)
         {
            Console.WriteLine(e.Message);
         }
      }

我对Lambda表达式感到困惑:

var secondTask = firstTask.ContinueWith((t) => CreateSummaryFile(path));

目的是什么:(t)?为什么它包含在括号中? t没有在任何地方定义。

我已阅读此网页,但未回答我的问题:https://msdn.microsoft.com/en-us/library/bb397687.aspx

3 个答案:

答案 0 :(得分:1)

Task.ContinueWith需要一个Action<Task> - 一个接受Task作为参数的“方法”。 t将成为TaskContinueWith提供该方法的参数。

该方法类似于:

void noName(Task t)
{
    CreateSummaryFile(path);
}

ContinueWith然后会在适当的时候执行此匿名方法,为其提供t(将被忽略),并调用CreateSummaryFile(path)

答案 1 :(得分:1)

如果你意识到那里使用的表格有一个简写并且完整形式是:

,那也许会更清楚一点。
(Task t) => CreateSummaryFile(path)

它定义了Action<Task>,因此t is not defined anywhere的计数器实际上是在那里定义的。

当可以从上下文推断时,你可以省略该类型(就像在这里一样)。当只有一个参数时,你也可以省略括号,所以这也可以是:

t => CreateSummaryFile(path)

现在,t并未在此处使用,但它经常使用,而且非常有用。更重要的是,在ContinueWith上调用Task<TResult>时,t的类型将为Task<TResult>,结果可用于后续任务。

有些人喜欢使用_来表示用于发出信号的参数,我必须在此处输入一个参数,但它没有做任何事情。但是后来有些人也讨厌那种惯例。 YMMV。

答案 2 :(得分:0)

The signature of ContinueWith is

Task ContinueWith(Action<Task> continuationAction)

Action<Task>部分意味着您必须使用一个类型为Task的输入参数并返回void来传递委托。也就是说,ContinueWith将在适当的时间调用该委托并传递Task类型的参数。

C#中的lamdba表达式是委托的简写。 lambda运算符(=>)的左边是参数,右边是将要执行的正文。由于您将获得类型为Task的参数,因此您将需要该类型的参数。在你的情况下是t。你不需要这个值也没什么区别。您仍然需要声明它以满足lamdba表达式的签名。