一.概念
可以将lambda表达式理解为匿名函数的简写
除了写法不同,使用上和匿名函数一样,都是配合委托或事件使用.
二.语法
(参数列表) =>
{
//函数体
}
//对比匿名函数
delegate(参数列表)
{
//函数体
}
三.使用
//无参无返回
//但不能直接这样使用,要结合事件委托
//() =>
//{
// Console.WriteLine("无参无返回");
//}
Action a =() =>
{
Console.WriteLine("无参无返回");
};
a();
Action<int> a2 = (int value) =>
{
Console.WriteLine("一个参数");
};
a2(3);
//可以省略参数类型
Action<int> a3 = (value) =>
{
Console.WriteLine("省略参数类型"):
};
a3(3);
//有返回值
Func<string, int> a4 = (value) =>
{
Console.WriteLine("参数string,返回值int");
};
a4("string");
四.闭包
闭包: 内层的函数引用包含在它外层的函数的变量,即使外层函数的执行已经终止.
该变量提供的值并非变量创建时的值,而是在父函数范围内的最终值.
class Test
{
public event Action a;
public Test()
{
int value = 10;
a = () =>
{
Console.WriteLine(value);//形成闭包
//lambda表达式里调用了一个已经被回收的临时变量
};
}
public void TestFunc()
{
a();//因为value的生命周期被改变,所以在这里还是可以调用value
}
}
//原本value在构造函数结束后会被回收,但现在会被a一直占用保存,除非置空a
//value的生命周期被改变
class Test
{
public event Action a;
public Test()
{
for (int i = 0; i < 10; i++)
{
a += () =>
{
Console.WriteLine(i);
};
}
}
public void TestFunc()
{
a();
}
}
//这里会输出10遍10,输出的是最终i,而不是每一次循环的i
//for循环在不断往事件传值,而一直没用调用,当调用时,会使用最终保存的值
//若想要输出0-9
class Test
{
public event Action a;
public Test()
{
for (int i = 0; i < 10; i++)
{
int index = i;
a += () =>
{
Console.WriteLine(index);
};
}
}
public void TestFunc()
{
a();
}
}
//这样每次保存临时变量时都会保存一个新的临时变量,即使名字相同,但实际每次的临时变量都是不同变量
//下一次的index与上一次无关
资料来源<唐老狮C#教程>