[英]C# lambda use local variable
class Program
{
static Action act = null;
static void Main(string[] args)
{
Test();
act();
act();
Test();
act();
}
static void Test()
{
int count = 0;
if(act == null) act = () => Console.Write(++count + " ");
}
}
result : 1 2 3
why?结果:
1 2 3
为什么?
if delete
[ if(act == null)
] result : 1 2 1
如果
delete
[ if(act == null)
]结果: 1 2 1
Currently, you're only creating a single delegate instance.目前,您只创建一个委托实例。 That captures the local variable that was declared in the
Test
method the first time it was called.这将捕获第一次调用
Test
方法时声明的局部变量。
That local variable effectively has an extended lifetime due to the delegate that captures it.由于捕获它的委托,该局部变量有效地延长了生命周期。 Every time you invoke the delegate, it increments the same variable.
每次调用委托时,它都会增加相同的变量。
When you remove the if (act == null)
condition, you create a new delegate each time you call Test
, which means it captures a different count
local variable, starting at 0 each time.当您删除
if (act == null)
条件时,每次调用Test
时都会创建一个新委托,这意味着它会捕获不同的count
局部变量,每次都从 0 开始。 You're calling Test()
twice, and the delegate created through the first call is invoked twice (with output 1 then 2).您调用
Test()
两次,通过第一次调用创建的委托被调用两次(output 1 然后 2)。 The delegate create through the second call is only invoked once (with output 1).通过第二次调用创建的委托仅被调用一次(使用 output 1)。
When you call this code:当您调用此代码时:
act = () => Console.Write(++count + " ");
You capture the local variable count
within the action.您在操作中捕获局部变量
count
。 Each subsequent call to act()
uses this captured variable.对
act()
的每个后续调用都使用此捕获的变量。 So if it starts as 0, it becomes 1, 2, and then 3.所以如果它从 0 开始,它会变成 1、2,然后是 3。
So with the if(act == null)
part, you will only ever assign act
a single time, so the second call to Test()
doesn't reassign act
and doesn't capture the new count
variable.因此,使用
if(act == null)
部分,您只会分配一次act
,因此对Test()
的第二次调用不会重新分配act
并且不会捕获新的count
变量。 Therefore, it keeps using the original one, meaning it increments to 3.因此,它继续使用原始的,这意味着它增加到 3。
Without the if
statement, you capture the new count
variable each time you call Test()
, so it effectively resets to 0.如果没有
if
语句,每次调用Test()
时都会捕获新的count
变量,因此它实际上会重置为 0。
Without testing if act is null, when you call Test() for the second time, it assigns a new inline function to act.如果不测试 act 是否为 null,当您第二次调用 Test() 时,它会分配一个新的内联 function 来执行。
Each inline act() have access to a different count version in the heap memory.每个内联 act() 都可以访问堆 memory 中的不同计数版本。
To understand, think that the compiler "reminds" that each act has access to the last call to Test memory space.要理解,认为编译器“提醒”每个动作都可以访问最后一次调用 Test memory 空间。
Each time Test is called, it creates a distinct heap space, so count has different value.每次调用 Test 时,都会创建一个不同的堆空间,因此 count 具有不同的值。
If you test if act is null and not create a new act inline function, act use only one count.如果您测试 act 是否为 null 并且没有创建新的内联动作 function,则仅使用一个计数。
If you create a new act because of not testing if null, each act has access to a new count version like if it was a new instance of an object having count as member.如果您因为未测试 null 而创建新行为,则每个行为都可以访问新的计数版本,就像它是 object 的新实例一样,它被视为成员。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.