C#中的闭包和Lambda

lJo*_*son 11 c# lambda closures

我得到了闭包和lambda表达式的基本原理,但我试图将我的思想包围在幕后发生的事情以及何时在我的代码中使用它们是不切实际的.考虑以下示例,该示例采用名称集合并返回以字母C开头的任何名称...

    static void Main(string[] args)
    {
        List<string> names = new List<string>();
        names.AddRange(new string[]
        {
            "Alan", "Bob", "Chris", "Dave", "Edgar", "Frank"
        });


        names.FindAll(x => x.StartsWith("C")).ForEach(
            i => Console.WriteLine(i));

    }
Run Code Online (Sandbox Code Playgroud)

首先,有没有更直接的方法可以写出这个表达式?其次,是不是"FindAll"会为包含匹配项的新集合分配内存?我确实看到语法更优雅,但我想确保在处理更大的集合时,我不会在以后遇到性能问题.编译器是否在幕后做了一些优化巫术,使我的问题无效?

Joe*_*orn 15

是的,FindAll将创建一个新列表.您想要"Where",它将返回知道如何循环现有列表的IEnumerable对象:

foreach (string name in names.Where(n => n.StartsWith("C") ) ) 
{
    Console.WriteLine(name);
}
Run Code Online (Sandbox Code Playgroud)

但是代码中没有闭包,因为没有要捕获的局部变量.


Eri*_*ert 12

使用"Where"的其他答案是正确的.另外一点:您还可以使用查询理解语法使"Where"看起来更好:

   var query = from name in names where name.StartsWith("C") select name;
   foreach(var result in query) Console.WriteLine(result);
Run Code Online (Sandbox Code Playgroud)

请注意,作为一个风格问题,我建议表达式没有副作用,语句总是有副作用.因此,我个人会使用foreach 语句而不是ForEach 子表达式来执行输出副作用.许多人不同意这一点,但我认为它使代码更加清晰.

  • 那是一个很棒的习俗! (3认同)