7

この質問に触発されて、私は次の例がすべてc#で違法である理由を疑問に思い始めました:

VoidFunction t = delegate { int i = 0; };

int i = 1;

{
   int i = 0;
}

int i = 1;

言語がこのように設計された正確な理由を誰かが知っているかどうか疑問に思っていますか?悪いプログラミング慣行を思いとどまらせるためですか?もしそうなら、パフォーマンス上の理由(コンパイル時と実行時)または理由は何ですか?

4

3 に答える 3

9

この動作は、C# 言語仕様のセクション 3 で説明されています。仕様書からの引用です

同様に、ラムダ式の形式で無名関数の本体として発生する式は、無名関数のパラメーターを含む宣言空間を作成します。ローカル変数宣言空間の 2 つのメンバーが同じ名前を持つことはエラーです。ブロックのローカル変数宣言空間とネストされたローカル変数宣言空間に同じ名前の要素が含まれるとエラーになります。したがって、入れ子になった宣言空間内では、囲んでいる宣言空間内のローカル変数または定数と同じ名前のローカル変数または定数を宣言することはできません。

これを読みやすくする方法は、変数宣言 (および他の多くのブロック関連関数) の目的で、ラムダ/匿名デリゲート ブロックが通常のブロックと同じように扱われることだと思います。

言語がこのように設計された理由について、仕様は明示的に述べていません。私の意見ですが、シンプルです。コードが単なる別のブロックとして扱われる場合、コード分析ルーチンがより簡単になります。既存のすべてのルーチンを保持して、セマンティック エラーと名前解決についてブロックを分析できます。これは、可変リフティングを検討する場合に特に重要です。ラムダは最終的には別の関数になりますが、宣言ポイントでスコープ内のすべての変数にアクセスできます。

于 2009-01-01T17:29:04.923 に答える
2

このようにして、内側のスコープが外側のスコープで宣言された変数にアクセスできるようになっていると思います。外側のスコープに存在する変数を上書きすることが許可された場合、意図された動作について混乱が生じる可能性があります。そのため、問題が起こらないようにすることで問題を解決することを決定した可能性があります。

于 2009-01-01T17:31:12.623 に答える
0

開発者が足を撃たれるのを防ぐのはこの方法だと思います。

于 2009-01-01T18:07:50.600 に答える