这些例子是C#闭包吗?

tui*_*oel 13 c# closures

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

例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");
Run Code Online (Sandbox Code Playgroud)

例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");
Run Code Online (Sandbox Code Playgroud)

jal*_*alf 9

您的第二个示例使用闭包(从技术上讲,您可以说编译器在两种情况下都会计算闭包,但在第一种情况下您不会使用它).

闭包只是"此函数可见的所有变量".没有更多,没有更少.显然,在这两种情况下,这些变量都存在,并由编译器确定.

但是当我们谈论"使用闭包"时我们通常的意思是lambda表达式可以使用它们声明的位置处可见的所有局部变量.他们都是关闭的一部分.

在你的情况下,d简单地说就是lambda函数的参数,因为在第一种情况下你只使用它,你并没有真正利用闭包.

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

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

  • 第一个例子关闭`subFolders`,所以它也是一个闭包. (2认同)

Mar*_*o F 6

是的,一个闭包只不过是一个从定义它的环境中"保存"一些变量的函数.因此,在两个示例中,定义的操作都会保存名为list的列表subFolders,即使在局部变量超出范围之后,也可以由函数引用.filter第二个示例中的变量也由定义的函数保存.

这里有一个更精确的定义