Reputation: 497
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?
if delete
[ if(act == null)
]
result : 1 2 1
Upvotes: 4
Views: 347
Reputation:
Without testing if act is null, when you call Test() for the second time, it assigns a new inline function to act.
Each inline act() have access to a different count version in the heap memory.
To understand, think that the compiler "reminds" that each act has access to the last call to Test memory space.
Each time Test is called, it creates a distinct heap space, so count has different value.
If you test if act is null and not create a new act inline function, act use only one count.
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.
Upvotes: 1
Reputation: 1500525
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.
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. You're calling Test()
twice, and the delegate created through the first call is invoked twice (with output 1 then 2). The delegate create through the second call is only invoked once (with output 1).
Upvotes: 11
Reputation: 38767
When you call this code:
act = () => Console.Write(++count + " ");
You capture the local variable count
within the action. Each subsequent call to act()
uses this captured variable. So if it starts as 0, it becomes 1, 2, and then 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. Therefore, it keeps using the original one, meaning it increments to 3.
Without the if
statement, you capture the new count
variable each time you call Test()
, so it effectively resets to 0.
Upvotes: 3