4

なぜこれが問題ないのか、誰かが私に雄弁で詳細な説明をしてくれませんか:

EventHandler e;

private void foobar(){
     e = new EventHandler((o, s) => {
           somectl.LayoutUpdated -= e;
     }
     somectl.LayoutUpdated += e;
}

しかし、これはそうではありません:

private void foobar(){
     EventHandler e = new EventHandler((o, s) => {
           somectl.LayoutUpdated -= e;
     }
     somectl.LayoutUpdated += e;
}

これもそうではありません:

private void foobar(){
    EventHandler e;
    e = new EventHandler((o, s) => {
          somectl.LayoutUpdated -= e;
    }
    somectl.LayoutUpdated += e;
}
4

3 に答える 3

2

e割り当てを完了する前に参照できないため、最後の 2 つはコンパイルされません。

この制限はフィールドには適用されないため、最初のものは機能します。

null確実に割り当てられるように、最初に割り当てることで最後の 1 つを機能させることができます。

EventHandler e = null;
e = (o, s) => {
      somectl.LayoutUpdated -= e;
};
somectl.LayoutUpdated += e;
于 2012-04-12T14:15:11.977 に答える
2

これは、思ったほどラムダとは関係ありません。たとえば、これは失敗します。

int i = i + 1;

これは次のようになります。

int i;
if (condition) {i = 0;}
i = i + 1;

または:

int i;
if (condition) {Console.WriteLine(i);}
i = 1;

ラムダ式は同じ理由で失敗します。真ん中の理由は、宣言内で変数を参照できないためであり、最後の理由はe、ラムダ内で使用する前に変数が初期化されていることを保証できないためです。

フィールドは常に初期化されるため、最初の例は問題なく動作します。クラスのコンストラクターで値が与えられるか、自動的にデフォルトに設定されます。メソッドのスコープ内でこれを機能させたい場合は、変数を宣言するときに変数を割り当てるだけです。

private void foobar(){
    EventHandler e = null;
    e = new EventHandler((o, s) => {
          somectl.LayoutUpdated -= e;
    }
    somectl.LayoutUpdated += e;
}
于 2012-04-12T14:18:06.023 に答える