Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of unassigned local variable when creating an anonymous function closing on itself

Why does this declaration+assignment cause an error:

// Use of unassigned local variable 'handler'.
SessionEndingEventHandler handler = (sender, e) => { isShuttingDown = true; SystemEvents.SessionEnding -= handler; };

while this does not:

SessionEndingEventHandler handler = null;
handler = (sender, e) => { isShuttingDown = true; SystemEvents.SessionEnding -= handler; };

In is intuitive that the first statement should cause an error but not immediately clear why the second one is not.

Furthermore, how could I tell if the SystemEvents.SessionEnding event has been actually unsubscribed after the call to handler(null, null)? The GetInvocationList only works with delegates.

SystemEvents.SessionEnding += handler;
handler(null, null);
like image 742
Raheel Khan Avatar asked Oct 11 '15 01:10

Raheel Khan


People also ask

What does use of unassigned local variable mean C#?

Use of unassigned local variable 'name' The C# compiler doesn't allow the use of uninitialized variables. If the compiler detects the use of a variable that might not have been initialized, it generates compiler error CS0165.

What does unassigned mean in C?

An unassigned variable in C is not "an unknown", though it is (as an adjective) unknown. It's uninitialized and thus equal to some value though it must be initialized first in order to be useful since only then do we know how to predict its behavior.


1 Answers

It's for the same reason that you'd expect this to fail:

int i = 1 - i;

The right-hand side of the statement is evaluated before the assignment, and at the time when it's evaluated, the variable hasn't been assigned yet.

In case you think lambdas/delegates change things, consider the following statement:

int i = ((Action)() => 1 - i)();

Because you're creating the lambda before i is assigned, it's possible that i could be used before any value has been assigned to it. The fact that you don't expect that to happen in your case doesn't change things from the compiler's perspective--you have to explicitly assign a value to the variable before it's used. If it's a null value, then at least the compiler knows you're considering the possibility that it's going to be null when you get to it.

Regarding your final question, a SessionEndingEventHandler is a delegate. So this would work fine:

var unsubscribed = SystemEvents.SessionEnding == null ||
    !SystemEvents.SessionEnding.GetInvocationList().Contains(handler);
like image 84
StriplingWarrior Avatar answered Sep 29 '22 07:09

StriplingWarrior