デリゲートを使用する利点と利点は何ですか?誰でも簡単な例を提供できますか?
これらはコードの一部をカプセル化する優れた方法です。たとえば、ボタンにイベントハンドラーをアタッチすると、そのハンドラーはデリゲートになります。ボタンは、ボタンが何をするかを知る必要はなく、適切なタイミングで呼び出す方法を知っている必要があります。
別の例はLINQです-フィルタリング、投影などはすべて同じ種類のテンプレートコードを必要とします。変更点はすべて、フィルターやプロジェクションなどを表すロジックです。C#3のラムダ式(デリゲートまたは式ツリーに変換されます)を使用すると、非常に簡単になります。
var namesOfAdults = people.Where(person => person.Age >= 18)
.Select(person => person.Name);
(これはクエリ式として表すこともできますが、デリゲートから離れすぎないようにしてください。)
デリゲートのもう1つの考え方は、単一メソッドのインターフェース型です。たとえば、EventHandler
デリゲート型は次のようになります。
public interface IEventHandler
{
void Invoke(object sender, EventArgs e)
}
ただし、フレームワークでのデリゲートサポートにより、デリゲートを一緒にチェーンしたり、非同期的に呼び出したり、イベントハンドラーとして使用したりできます。
デリゲートとイベントの詳細については、 トピックに関する私の記事 を参照してください。その焦点はイベントですが、デリゲートもカバーします。
これはかなり漠然としたトピックですが、考慮すべき点がいくつかあります-
デリゲートは基本的に、よりクリーンで簡単な関数ポインターです。 C++で関数ポインターが使用された場所ならどこでも、デリゲートと考えることができます。
デザインでそれらを使用する利点:
[Func<T,bool>]
を使用してフィルタリングできます。 Whereメソッドのコード潜在的な欠点:
~can~
、特に単純に使用された場合、より読みにくいコードにつながりますデリゲートには、3つの目的があります。
観察者
public class Something
{
public event EventHandler SomethingHappened;
}
public class SomethingConsumer
{
private mySomething = new Something();
public void WireUpEvents()
{
mySomething.SomethingHappened += whenSomethingHappened;
}
private void whenSoemthingHappened(object sender, EventArgs e)
{
// do something
}
}
CallBack
public void DoSomethingAsynchronously(EventHandler callBack)
{
// long running logic.
callBack(this, EventArgs.Empty);
}
匿名の再利用できないコード
public void DoSomethingReusably(Action nonReusableCode)
{
// reusable code
nonReusableCode();
// more reusable code
}
public void DoALotOfSomething()
{
DoSomethingReusably(() => { /* non-reusable code here */ });
DoSomethingReusably(() => { /* non-reusable code here */ });
DoSomethingReusably(() => { /* non-reusable code here */ });
}
すべての場合において、それはただの簡潔さを提供することの問題です。
C#のデリゲートはeqvです。 Cの関数ポインタへのリンクですが、作成元のクラスインスタンスへの参照も含まれています。
Windowsフォームのすべてのイベントハンドラーはデリゲートです。
何と比較した場合の利点?デリゲートは便利なものになる可能性があり、適度に複雑な多数のC#コードの中で確かにその位置を占めます。 (クラスでイベントを使用する場合は常に、マルチキャストデリゲートを暗黙的に使用しています)。構文と使用法の紹介が必要な場合は、以下の記事をお勧めします。
免責事項:デリゲートの使用方法が意図された方法であるとは言いませんが、それは一例です。
私はこれを1度だけ使用しましたが、基本的に私たちのアプリでは、ユーザーがステップの[完了]ボタンをクリックすると、ルーティングページに移動して次に送信する場所を決定します。したがって、技術的には、「完了」をクリックしたステップは、ルーティングするまで実際には完了しません。しかし、私は別のページにいるので、彼らがいた場所に簡単にアクセスできませんでした。
だから私がしたことは、「完了」をクリックしたときに特別な処理(この場合はメール)を必要とするいくつかのステップのデリゲートを作成し、次のページでルーティングしたときにデリゲートの存在を確認し、私の「保存された」イベントを発生させるためにそれを呼び出しました。
クリエイティブ:多分、間違っている:多分、機能している:間違いなく。
私が言ったように、それがどのように使用されることが意図されていたのではないかもしれませんが、コーディングは科学と同じくらいアートですよね?
初期のJavaデリゲートやコマンドルーティングの概念がなかったGUIフレームワークを覚えています。何かを実行するボタンを作成するには、サブクラスボタンをオーバーライドする必要がありましたクリックメソッドを使用すると、アプリケーションコードのほんの少しだけのUI要素サブクラスがたくさん作成されます。
そのクリックを処理するコードはどこかに行く必要があり、OO JavaまたはC#のような言語では、クラスに行く必要がありますが、デリゲートはそれを許可しますこれは、多くのコードがフォームクラスでさまざまなことを実行しすぎることにつながりますが、それは別の問題です。