在创建关闭自身的匿名函数时使用未分配的局部变量

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);