C#中的Lambdas捕获外部变量 - 请从书中解释示例" C#简言之5.0"

时间:2014-05-19 12:17:06

标签: c# lambda

之间有什么区别
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?谢谢!

2 个答案:

答案 0 :(得分:11)

不同之处在于,在第一个版本中,您声明了一个变量,然后捕获 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;

请注意第一个版本中实例变量与第二个版本中 local 变量之间的差异。

(这不完全是第二种形式的实现看起来的样子;它将是封闭类中的静态方法,因为它是无状态的,但是......)

答案 1 :(得分:3)

在第一种情况下,每当调用Natural时,它返回一个函数,每次将{em>引用到同一个seed变量<{em> Natural }本身)。

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

理所当然,在第一种情况下,每个返回的函数都能够“看到”其他人对seed所做的更改,因为所有这些都在处理相同的值。