c#中的Lambdas捕获外部变量-请解释“c#概览5.0”书中的示例

本文关键字:概览 解释 Lambdas 中的 外部 变量 | 更新日期: 2023-09-27 18:04:07

static Func<int> Natural()
{
  int seed = 0;
  return () => seed++;      // Returns a closure
}

static Func<int> Natural()
{
  return() => { int seed = 0; return seed++; };
}

为什么
static void Main()
{
  Func<int> natural = Natural();
  Console.WriteLine (natural());       
  Console.WriteLine (natural());         
}

为第一个Natural()显示0 1,为第二个显示0 0 ?谢谢!

c#中的Lambdas捕获外部变量-请解释“c#概览5.0”书中的示例

不同之处在于,在第一个版本中,您声明了一个变量,然后在lambda表达式中捕获变量。变量本身在委托的多次调用中"存活"。

在第二个例子中,你在lambda表达式中声明了一个变量,所以每次执行委托时,该变量都有效地重新开始。

换句话说,就是

class NaturalImpl
{
    public int seed;
    public int Method()
    {
        return seed++;
    }
}
Func<int> natural = new NaturalImpl().Method;

:

class NaturalImpl
{
    public int Method()
    {
        int seed = 0;
        return seed++;
    }
}
Func<int> natural = new NaturalImpl().Method;

注意第一个版本中的实例变量与第二个版本中的局部变量之间的区别。

(这并不完全是第二个表单的实现看起来像;它将是封闭类中的静态方法,因为它是无状态的,但是…)

在第一种情况下,无论何时调用Natural,它都会返回一个函数,该函数每次都将引用到相同的seed变量(在Natural内部定义的变量)。

在第二种情况下,它返回一个函数,每次(在所述函数体内定义的那个)将引用到不同的seed变量。

显然,在第一种情况下,每个返回的函数都能够"看到"其他函数对seed的更改,因为它们都在处理相同的值。