Lambda 表达式中的变量范围 几个概念问题

SpeForce 2011-01-25 02:43:09
有下面这几句话,每句话该怎么理解,有的我写了一些自己的理解,不知道对不对。

捕获的变量将不会被作为垃圾回收,直至引用变量的委托超出范围为止。
我的理解:lambda中引用的变量 不论是外部还是lambda内部变量,都不会被垃圾回收, 直到这个委托所承载的方法超出范围.

在外部方法中看不到 Lambda 表达式内引入的变量。
这个不知道如何理解

Lambda 表达式无法从封闭方法中直接捕获 ref 或 out 参数。
这个不知道如何理解

Lambda 表达式中的返回语句不会导致封闭方法返回。
我的理解:lambda表达式return 只是跳出lambda ,然后继续执行方法中 lambda下面的语句,不会跳出lambda所在的方法。

Lambda 表达式不能包含其目标位于所包含匿名函数主体外部或内部的 goto 语句、break 语句或 continue 语句。
如何理解 比较绕
...全文
317 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
threenewbee 2011-01-26
  • 打赏
  • 举报
回复
贴一个正确的程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string s1 = "!";
MyMethod(s =>
{
Console.WriteLine(s + s1); //它可以认识外部的变量,反过来刚才说了,是不行的。其实这是一个编译器魔术。如果不懂 Lambda 的实质,反过来的时候不行了就会奇怪了。
return null;
});
}

static void MyMethod(Func<string, object> call)
{
call("Hello world");
}
}
}
threenewbee 2011-01-26
  • 打赏
  • 举报
回复
用几个例子来说明:
在外部方法中看不到 Lambda 表达式内引入的变量。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MyMethod(s =>
{
string s1 = s + "!";
Console.WriteLine(s1);
return null;
});
Console.WriteLine(s1); // 出错,它看不到 Lambda 里面的 s1
}

static void MyMethod(Func<string, object> call)
{
call("Hello world");
}
}
}


Lambda 表达式无法从封闭方法中直接捕获 ref 或 out 参数。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string s = "!";
FuncWithIn(ref s);
}

static void FuncWithIn(ref string s1)
{
MyMethod(s =>
{
Console.WriteLine(s + s1); //出错,没办法使用 ref
return null;
});
}

static void MyMethod(Func<string, object> call)
{
call("Hello world");
}
}
}


Lambda 表达式中的返回语句不会导致封闭方法返回。
这个最好理解了。Lambda 的 return 返回的是 Lambda 方法,不是调用函数

Lambda 表达式不能包含其目标位于所包含匿名函数主体外部或内部的 goto 语句、break 语句或 continue 语句。
Lambda不能goto到主函数里面去
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MyMethod(s =>
{
Console.WriteLine(s);
goto Label1;
return null;
});
Label1:
Console.WriteLine("Label1 here.");
}

static void MyMethod(Func<string, object> call)
{
call("Hello world");
}
}
}


垃圾回收的,你必须仔细看 MSDN 了。


其实这些问题都很简单,只是说得很复杂。前提是,你如果知道 Lambda 表达式内部是一个匿名的函数,它是独立存在的,这些问题都好理解。
KissXYL 2011-01-26
  • 打赏
  • 举报
回复
lambda编译后就是一个方法,你就当你代码是简化的方法定义书写即可。
wuyq11 2011-01-25
  • 打赏
  • 举报
回复
SpeForce 2011-01-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 q107770540 的回复:]

Lambda 可以引用“外部变量”,这些变量位于在其中定义 Lambda 的封闭方法或类型的范围内。 将会存储通过这种方法捕获的变量以供在 Lambda 表达式中使用,即使变量将以其他方式超出范围或被作为垃圾回收。 必须明确地分配外部变量,然后才能在 Lambda 表达式中使用该变量。
http://msdn.microsoft.com/zh-cn/library/bb397687.aspx
……
[/Quote]
MSDN语言太抽象,可以解释一下吗
q107770540 2011-01-25
  • 打赏
  • 举报
回复
Lambda 可以引用“外部变量”,这些变量位于在其中定义 Lambda 的封闭方法或类型的范围内。 将会存储通过这种方法捕获的变量以供在 Lambda 表达式中使用,即使变量将以其他方式超出范围或被作为垃圾回收。 必须明确地分配外部变量,然后才能在 Lambda 表达式中使用该变量。
http://msdn.microsoft.com/zh-cn/library/bb397687.aspx

8,497

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 LINQ
社区管理员
  • LINQ
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧