我是C#的新手并尝试了解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
。它仅在d1
稍后调用testMethod
后才更改。那么如何打印True
?我在这里错过了什么?
答案 0 :(得分:6)
d1
和d2
都引用j
的同一个实例。当您通过调用j
设置d1
时,您也会改变d2
可以看到的变量的值。
如果你想要它们有j
的不同实例,你需要对变量进行范围调整:
{
int j = 0;
d1 = () => { j = 10; return j < input; };
}
{
int j = 0;
d2 = (x) => { return x == j; };
}
但是,如果您要这样做,那么您可能会有两个不同的变量,比如j1
和j2
。这将更具可读性。
答案 1 :(得分:3)
创建委托时,会捕获其使用范围之外的任何变量。在这种情况下,分配给d1
和d2
的代理都会捕获j
内声明的变量testMethod()
;他们不创建j
的副本,他们捕获实际变量。从这个意义上说,在d1
和d2
的生命周期中,j
在它们内部表现就好像它是一个全局变量(尽管在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);
}