【问题标题】:Use of unassigned local variable when creating an anonymous function closing on itself创建关闭自身的匿名函数时使用未分配的局部变量
【发布时间】:2015-10-11 01:20:00
【问题描述】:

为什么这个声明+赋值会报错:

// 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; };

很直观,第一个语句应该会导致错误,但不能立即清楚为什么第二个语句不会。

此外,在调用handler(null, null) 之后,我如何判断SystemEvents.SessionEnding 事件是否实际上已取消订阅? GetInvocationList 仅适用于代表。

SystemEvents.SessionEnding += handler;
handler(null, null);

【问题讨论】:

  • 第一个语句更等同于SessionEndingEventHandler handler;,而在第二个语句中你将它赋值为null。在完全构造 lambda 之前,它是未分配的。见stackoverflow.com/questions/1362204/…

标签: c# .net variables delegates unassigned-variable


【解决方案1】:

出于同样的原因,您期望这会失败:

int i = 1 - i;

语句的右侧是在赋值之前求值的,而在求值时,变量还没有被赋值。

如果您认为 lambdas/delegates 改变了事情,请考虑以下语句:

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

因为您是在分配 i 之前创建 lambda,所以 可能 可以在分配任何值之前使用 i。从编译器的角度来看,您不希望在您的情况下发生这种情况并不会改变事情——您必须在使用变量之前显式地为其赋值。如果它是一个空值,那么至少编译器知道你正在考虑当你得到它时它会为空的可能性。

关于您的最后一个问题,SessionEndingEventHandler 代表。所以这会很好:

var unsubscribed = SystemEvents.SessionEnding == null ||
    !SystemEvents.SessionEnding.GetInvocationList().Contains(handler);

【讨论】:

    猜你喜欢
    • 2019-06-05
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    • 2018-05-11
    相关资源
    最近更新 更多