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

时间:2015-10-11 01:20:01

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

为什么此声明+赋值会导致错误:

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

1 个答案:

答案 0 :(得分:10)

出于同样的原因,您预计会失败:

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); 代表。所以这样可以正常工作:

func loadPlaces() {
    startActivityIndicator()
    dataProvider.fetchPlacesNearCoordinate(coordinate, radius:searchRadius, types: searchedTypes) { places in
        stopActivityIndicator()
        //append places object to your data
        self.tableView.reloadData()
      }
}