这些例子是C#闭包吗?

我仍然不太明白什么是闭包 ,所以我发布了这两个例子,我想知道这些例子是否都是闭包?

示例A:

List<DirectoryInfo> subFolders = new List<DirectoryInfo>();

Action<string> FilterSubFoldersStartA =
  s => subFolders.
       AddRange((new DirectoryInfo(s)).GetDirectories().
       Where(d => d.Name.StartsWith("A")));

FilterSubFoldersStartA(@"c:tempa");
FilterSubFoldersStartA(@"c:tempb");

例子B:

List<DirectoryInfo> subFolders = new List<DirectoryInfo>();

string filter = "A";

Action<string> FilterSubFoldersStartGen =
  s => subFolders.
       AddRange((new DirectoryInfo(s)).GetDirectories().
       Where(d => d.Name.StartsWith(filter)));

FilterSubFoldersStartGen(@"c:tempa");

filter = "B"; 

FilterSubFoldersStartGen(@"c:tempb");

是的,闭包只不过是一个函数,可以将它定义的环境中的某些变量“保存”起来。 因此,在这两个示例中,已定义的操作都会保存名为subFolders的列表,即使在局部变量超出范围之后,该列表也可以由函数引用。 第二个例子中的filter变量也由定义的函数保存。

这里有一个更精确的定义


你的第二个例子使用了闭包(在技术上你可以说编译器在两种情况下计算闭包,但在第一种情况下你不会使用它)。

闭包简单地说就是“这个函数可见的所有变量”。 没有更多,没有更多。 显然,在这两种情况下,这些变量都存在,并由编译器决定。

但是当我们谈论“使用闭包”时,我们通常的意思是,lambda表达式可以在声明的地方使用所有可见的局部变量。 它们都是关闭的一部分。

在你的情况下, d只是lambda函数的参数,因为这就是你在第一种情况下使用的所有东西,所以你并没有真正利用闭包。

在第二种情况下, filter没有在lambda表达式中定义,它不是一个参数或任何东西。 这是一个局部变量,恰好在声明lambda的地方可见。 所以它是lambda封闭的一部分,它允许你在lambda体内引用它。

编辑
正如评论中指出的那样,我没有仔细阅读你的代码。 我只注意到每个例子中的第二个lambda表达式。 第一个lambda使用闭包(在两种情况下它都关闭子文件subFolders )。


这两个例子都有关闭。 在“A”中,匿名方法捕获局部变量子文件夹。 在“B”中,匿名方法捕获局部变量子文件夹和过滤器。 也请看看这里。

PS还要注意,你实际上在“A”中使用闭包,因为你正在使用子文件夹变量。

链接地址: http://www.djcxy.com/p/51095.html

上一篇: Are these examples C# closures?

下一篇: MVC3 return multiple pdfs as a zip file