2

次のように宣言されたボタンイベントがあります。

myButton.Click += new EventHandler(ButtonClicked);

private void ButtonClicked(Object s, EventArgs e)
{
  this.Close();
}

私はこのようにまったく同じことができます:

myButton.Click += (s, e) => this.Close();

2 番目の方法を使用する利点は、見た目だけではないと確信しています。

混乱しているのに、なぜ、いつ、2 番目の方法を使用する必要があるのでしょうか? 見た目だけの場合、無名関数の本体に複数の命令があると、あまりきれいに見えません。

4

8 に答える 8

4

技術的には違いはありません。2 番目のケースでは、コンパイラはハンドラ メソッドを生成します。

しかし、率直に言って、匿名のイベント ハンドラーを使用することはほとんどありません。なんで?彼らには名前がないからです。IDE は、イベントが処理される場所を見つけるのに役立ちません。匿名の方法で購読した正確な場所を覚えていますか? まあ、あなたはおそらくその場所を覚えています。しかし、あなたのチームメイトはそうではないと思います。

また、イベント ハンドラーのスタイルを混在させるのも好きではありません。Visual Studio がbutton1_Clickメソッドを生成します。この方法でサブスクライブされたハンドラーと、その場でサブスクライブされたハンドラーがあるのは好きではありません。

そして、イベントの引数の型を見るのが好きです。そして、はい、購読解除もいつか重要です。さらにいくつかのポイント-匿名メソッドは非常に単純なロジック(あなたの場合はフォームを閉じるなど)に役立ちますが、より複雑なものでは非常に面倒になります。そして、イベントハンドラーを配置すると、メソッドの単一の責任が壊れると思います。イベントをサブスクライブし、他のことを行い、同じ場所でイベントを処理します。読みやすく、保守しやすいように、物事を分離するのが好きです。

于 2013-02-20T14:16:54.503 に答える
2

コンパイラは、(s, e) => this.Close();どちらの方法でも、この無名関数のメソッドを生成します。

どこで使用するかはあなた次第ですが、メソッド内で宣言すると、そのメソッドで宣言された変数にアクセスできます。

于 2013-02-20T14:02:44.547 に答える
1

匿名関数は、匿名メソッドまたはラムダ式にすることができます。ランバ式は次の形式です。

() => //dowork

匿名メソッドはより冗長であり、サポートは主に下位互換性のために残っています。匿名関数には、それ自体に値や型はありませんが、デリゲートまたは式ツリーに変換できます。匿名関数を使用すると、イベントハンドラーの設定などの場合に役立つインラインメソッドを作成できます。このメソッドのインライン化により、開発者は「同じ場所に」コードを記述できます。つまり、ハンドラーは、イベントが処理される場所でリーダーがすぐに使用できるようになります。

実装がいくつかのステートメントに制限されており、再利用できない場合は、インラインメソッドに努めています(イベントハンドラーでよくあることです)。Lamba式は、フレームワークの拡張メソッドなどで広く使用することもできます Enumerable.Select。また、新しい並列ライブラリを使用したり、を呼び出したりするWhere代わりに、Actionまたはそのときに使用できます。FuncControl.Invoke

于 2013-02-20T14:14:48.253 に答える
1

引数が必要ない場合は、さらにエレガントに行うことができます。

myButton.Click += delegate { this.Close(); };

しかし、その背後にあるエレガントな外観以外に利益はありません。

デバッグ中にスコープコードを変更できないため、ラムダ式(=>)が本当に必要ない場合は、ラムダ式(=>)を使用しないことをお勧めします。

于 2013-02-20T14:08:16.820 に答える
1

さて、本質的に暗黙のうちにデリゲートをClickイベントに適用しました。

他の場所のコードでこのイベントにアクセスすることはできません。これの主な利点は、他の「チームメンバー」を招待してコード内のメソッドにアクセスさせたり、修飾子を変更する可能性があるため、クラス内の他の場所でメソッドを呼び出すことができないことです。起こるべきだと思います。

メソッドを実行できるようにしたい場合overrideは、インラインの匿名代入は明らかに不利です。

使用法は、ロジックへのアクセスをどのように処理するかによって多少異なります。

于 2013-02-20T14:04:51.457 に答える
0

パラメータが必要ない限り、次を使用することもできます。

myButton.Click += delegate { this.Close(); };

これはさらにきれいに見えます。

しかし、他の人が指摘しているように、匿名のデリゲートを使用すると、コードの再利用性が犠牲になります。記事「方法:イベントの購読と購読解除」にもあります。Microsoftは次のように述べています。

匿名関数を使用してイベントをサブスクライブした場合、イベントのサブスクライブを簡単に解除できないことに注意することが重要です。このシナリオでサブスクライブを解除するには、イベントをサブスクライブするコードに戻り、anonymousメソッドをデリゲート変数に格納してから、デリゲートをイベントに追加する必要があります。一般に 、コードの後半でイベントのサブスクライブを解除する必要がある場合は、匿名関数を使用してイベントをサブスクライブしないことをお勧めします

ラムダ式からも分離する匿名メソッドの長所の1つは、次のとおりです。

...匿名メソッドがラムダ式にはない機能を提供する場合が1つあります。匿名メソッドを使用すると、パラメータリストを省略できます。これは、匿名メソッドをさまざまな署名を持つデリゲートに変換できることを意味します。 これはラムダ式では不可能です。

上記の段落の結論として、パラメーターをまったく渡さないか、イベントハンドラーの正確な署名を渡す必要があると言えます。

myButton.Click += delegate(object sender, EventArgs e) { this.Close(); };
于 2013-02-20T14:08:41.743 に答える
0

似たようなテーマがあります:デリゲート キーワードと、匿名のデリゲートとラムダ式を考慮したラムダ表記法。特に、答えは次のとおりです。コンパイルすると、それらの間に違いはありません。

于 2013-02-20T14:06:18.617 に答える
0

最初の方法は、サポートしやすく、より複雑にし、再利用するのが簡単です。

また、イベントから 2 番目のメソッドのサブスクライブを解除する方法も明らかではありません

于 2013-02-20T14:03:20.163 に答える