lambda表达式中的对象范围
问题描述:
我是C#的新手,并试图了解lambda表达式以及代表。这是我运行的代码:lambda表达式中的对象范围
delegate bool D1();
delegate bool D2(int i);
namespace Console
{
class Program
{
D1 d1;
D2 d2;
public void testMethod(int input)
{
int j = 0;
d1 =() => { j = 10; return j < input; };
d2 = (x) => { return x == j; };
System.Console.WriteLine("j = {0}", j);
bool res = d1();
System.Console.WriteLine("res={0}, j ={1}", res, j);
}
static void Main(string[] args)
{
Program p = new Program();
p.testMethod(10);
System.Console.WriteLine(p.d2(10));
System.Console.ReadKey();
}
}
}
什么我不明白的是d2
打印true
调用。当构造d2
时,j
的值为0
。只有在testMethod
后面调用d1
后才发生更改。那么如何印刷True
?我在这里错过了什么?
答
d1
和d2
都指代j
的相同实例。当您通过调用d1
来设置j
时,您还在更改d2
可以看到的变量的值。
如果你希望他们做的有j
不同情况下你需要范围的变量:
{
int j = 0;
d1 =() => { j = 10; return j < input; };
}
{
int j = 0;
d2 = (x) => { return x == j; };
}
但是,如果你要做到这一点,那么你可能也有两个不同的变量,代替j1
和j2
。这将更具可读性。
答
当您创建一个委托时,捕获了它使用的范围之外的任何变量。在这种情况下,分配到d1
和d2
的代表都捕获testMethod()
内声明的变量j
;他们不创建j
的副本,他们捕获实际变量。从这个意义上说,在d1
和d2
,的生命周期中,它们的行为就好像它是一个全局变量(尽管当然在C#中没有这样的东西像全局变量)。
如果您希望这些方法获得单独的j
实例,则需要为每种方法提供j
的副本,而不是仅使用它。例如:
public void testMethod(int input)
{
int j = 0;
int k = j;
d1 =() => { j = 10; return j < input; };
d2 = (x) => { return x == k; };
System.Console.WriteLine("j = {0}", j);
bool res = d1();
System.Console.WriteLine("res={0}, j ={1}", res, j);
}
谢谢..有什么办法可以控制这个,以便`d1`&`d2`将单独的`j`实例? – Naveen 2011-12-16 12:34:55