6

この宣言+代入がエラーを引き起こすのはなぜですか:

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

In は、最初のステートメントがエラーを引き起こすべきであることは直観的ですが、2 番目のステートメントがそうでない理由をすぐには明らかにしません。

SystemEvents.SessionEndingさらに、への呼び出し後にイベントが実際にサブスクライブ解除されたかどうかをどのように確認できhandler(null, null)ますか? はGetInvocationListデリゲートでのみ機能します。

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

1 に答える 1

10

これが失敗すると予想されるのと同じ理由です。

int i = 1 - i;

ステートメントの右側は代入の前に評価され、評価された時点では、変数はまだ代入されていません。

ラムダ/デリゲートが物事を変えると思う場合は、次のステートメントを検討してください。

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

iが割り当てられる前にラムダを作成しているため、値が割り当てられる前に使用できる可能性があります。iあなたのケースでそれが起こるとは思わないという事実は、コンパイラの観点から物事を変えるものではありません.変数を使用する前に、変数に明示的に値を代入する必要があります. それが null 値である場合、少なくともコンパイラは、到達したときに null になる可能性を考慮していることを知っています。

最後の質問ですが、aSessionEndingEventHandler デリゲートです。したがって、これはうまくいきます:

var unsubscribed = SystemEvents.SessionEnding == null ||
    !SystemEvents.SessionEnding.GetInvocationList().Contains(handler);
于 2015-10-11T01:46:27.277 に答える