目录
lambda表达式
闭包
内层的函数可以引用包含在它外层的函数的变量
即使外层函数的执行已经终止
注意:
该变量提供的值并非变量创建时的值,而是在父函数范围内的最终值。
class Program
{
public static void Main()
{
Test test = new Test();
test.DoSomeThing(); //输出10 20
test .DoSomeThing(); //输出20 30
这两次输出不同证明了事件中存的匿名函数中的vlue是存的成员变量value的地址
因为第一次test.doSomeTing();value地址中的值是10第二个匿名方法把value地址中的值改为了20
第二次执行事件中的两个匿名函数时,第一个匿名函数执行时value的值变为了20 所以输出20 第二个匿名函数value地址中存的值变为了30所以输出30
}
}
class Test
{
public event Action action;
public Test()
{
int value = 10;
//这里就形成了闭包
//因为 当构造函数执行完毕时 其中申明的临时变量value的生命周期被改变了
action = () =>
{
Console .WriteLine (value);
};
action += () =>
{
value += 10;
Console.WriteLine (value);
};
}
public void DoSomeThing()
{
action();
}
}
一个例子
class Program{public static void Main(){Test test = new Test();test.DoSomeThing(); }}
class Test
{public event Action action;public Test() {for (int i = 0; i < 10; i++){action += () =>{Console.WriteLine(i); //这里为什么打印出来10个10;而不是0~9}; //因为存这个函数的时候Test这个构造函数还没执行完//i的值一直在+1+1,而函数中存的是i的地址} //等存的函数开始执行的时候 i的地址里就是10了//就打印了10个10} public void DoSomeThing() { action(); }
}
再来一个
class Program{public static void Main(){Test test = new Test();test.Fun()();}}
class Test
{public event Action action;public Action Fun() {for (int i = 1; i <=10; i++){int a = i;action += () =>{Console.WriteLine(a);};}return action; } }
这里打印1 2 3 4 5 6 7 8 9 10
lambda表达式
//可以将lambad表达式 理解为匿名函数的简写
//它除了写法不同外
//使用上和匿名函数一模一样
//都是和委托或者事件 配合使用的
lambad表达式语法
匿名函数
delegate (参数列表)
{
};
lambad表达式
(参数列表) =>
{
函数体
};
使用
//1.无参无返回
Action a = () =>
{
Console.WriteLine("无参无返回值的lambad表达式");
};
a();
//2.有参
Action<int> a2 = (int value) =>
{
Console.WriteLine("有参数Lambad表达式{0}", value);
};
a2(100);
//3.甚至参数类型都可以省略 参数类型和委托或事件容器一致
Action<int> a3 = (value) =>
{
Console.WriteLine("省略参数类型的写法{0}", value);
};
a3(200);
//4.有返回值
Func<string, int> a4 = (value) =>
{
Console.WriteLine("有返回值有参数的那么大表达式{0}", value);
return 1;
};
Console.WriteLine(a4("123123"));
//其它传参使用等和匿名函数一样
//缺点也是和匿名函数一样的