在创建关闭自身的匿名函数时使用未分配的局部变量
Use of unassigned local variable when creating an anonymous function closing on itself
为什么这个声明+赋值会报错:
// Use of unassigned local variable 'handler'.
SessionEndingEventHandler handler = (sender, e) => { isShuttingDown = true; SystemEvents.SessionEnding -= handler; };
虽然这不是:
SessionEndingEventHandler handler = null;
handler = (sender, e) => { isShuttingDown = true; SystemEvents.SessionEnding -= handler; };
根据直觉,第一个语句应该会导致错误,但不能立即弄清楚为什么第二个语句不会。
此外,我怎么知道 SystemEvents.SessionEnding
事件在调用 handler(null, null)
之后是否真的被取消订阅了? GetInvocationList
仅适用于代表。
SystemEvents.SessionEnding += handler;
handler(null, null);
这与您预期失败的原因相同:
int i = 1 - i;
语句的右侧在赋值之前求值,在求值时,变量还没有被赋值。
如果您认为 lambdas/delegates 改变事物,请考虑以下声明:
int i = ((Action)() => 1 - i)();
因为您是在分配 i
之前创建 lambda,所以 可能 i
可以在分配任何值之前使用.从编译器的角度来看,您不希望在您的情况下发生这种情况这一事实并没有改变——您必须在使用变量之前显式地为其赋值。如果它是一个 null 值,那么至少编译器知道你正在考虑当你到达它时它会成为 null 的可能性。
关于你的最后一个问题,SessionEndingEventHandler
是代表。所以这会很好用:
var unsubscribed = SystemEvents.SessionEnding == null ||
!SystemEvents.SessionEnding.GetInvocationList().Contains(handler);
为什么这个声明+赋值会报错:
// Use of unassigned local variable 'handler'.
SessionEndingEventHandler handler = (sender, e) => { isShuttingDown = true; SystemEvents.SessionEnding -= handler; };
虽然这不是:
SessionEndingEventHandler handler = null;
handler = (sender, e) => { isShuttingDown = true; SystemEvents.SessionEnding -= handler; };
根据直觉,第一个语句应该会导致错误,但不能立即弄清楚为什么第二个语句不会。
此外,我怎么知道 SystemEvents.SessionEnding
事件在调用 handler(null, null)
之后是否真的被取消订阅了? GetInvocationList
仅适用于代表。
SystemEvents.SessionEnding += handler;
handler(null, null);
这与您预期失败的原因相同:
int i = 1 - i;
语句的右侧在赋值之前求值,在求值时,变量还没有被赋值。
如果您认为 lambdas/delegates 改变事物,请考虑以下声明:
int i = ((Action)() => 1 - i)();
因为您是在分配 i
之前创建 lambda,所以 可能 i
可以在分配任何值之前使用.从编译器的角度来看,您不希望在您的情况下发生这种情况这一事实并没有改变——您必须在使用变量之前显式地为其赋值。如果它是一个 null 值,那么至少编译器知道你正在考虑当你到达它时它会成为 null 的可能性。
关于你的最后一个问题,SessionEndingEventHandler
是代表。所以这会很好用:
var unsubscribed = SystemEvents.SessionEnding == null ||
!SystemEvents.SessionEnding.GetInvocationList().Contains(handler);