web-dev-qa-db-ja.com

デリゲートとは何ですか?

デリゲートの実際の役割は何ですか?

私はインタビューで何度もこの質問をされましたが、インタビュアーが私の答えに満足しているとは思いません。

誰もが実用的な例を使って最高の定義を一文で教えてもらえますか?

145
Naveed

私はデリゲートを「関数へのポインタ」と考えるのが好きです。これはC時代に遡りますが、その考えはまだ保持されています。

アイデアは、あなたがコードの一部を呼び出すことができる必要があるということですが、あなたが呼び出すコードの一部は、実行時までわからないのです。そのため、そのために「デリゲート」を使用します。デリゲートは、イベントハンドラーなど、さまざまなイベントに基づいてさまざまなことを行う場合などに役立ちます。

こちら 参照できるC#のリファレンス:

たとえば、C#で、実行したい計算があり、実行時までわからない別の計算方法を使用したいとします。したがって、次のようないくつかの計算方法があります。

public static double CalcTotalMethod1(double amt)
{
    return amt * .014;
}

public static double CalcTotalMethod2(double amt)
{
    return amt * .056 + 42.43;
}

次のようなデリゲート署名を宣言できます。

public delegate double calcTotalDelegate(double amt);

そして、次のようにデリゲートをパラメーターとして取るメソッドを宣言できます。

public static double CalcMyTotal(double amt, calcTotalDelegate calcTotal)
{
    return calcTotal(amt);
}

そして、使用したいデリゲートメソッドを渡すCalcMyTotalメソッドを呼び出すことができます。

double tot1 = CalcMyTotal(100.34, CalcTotalMethod1);
double tot2 = CalcMyTotal(100.34, CalcTotalMethod2);
Console.WriteLine(tot1);
Console.WriteLine(tot2);
159
dcp

デリゲートは単なる関数ポインターです。
単純に、デリゲートを実行するメソッドを割り当てます。その後、コードの中でInvokeを介してそのメソッドを呼び出すことができます。

デモンストレーションするコード(メモリからこれを書いたため、構文がオフになる場合があります)

delegate void delMyDelegate(object o);

private void MethodToExecute1(object o)
{
    // do something with object
}

private void MethodToExecute2(object o)
{
    // do something else with object
}

private void DoSomethingToList(delMyDelegate methodToRun)
{
    foreach(object o in myList)
        methodToRun.Invoke(o);
}

public void ApplyMethodsToList()
{
    DoSomethingToList(MethodToExecute1);
    DoSomethingToList(MethodToExecute2);
}
18
Mladen Prajdic

ここから取得

[〜#〜] q [〜#〜]デリゲートとは何ですか?
[〜#〜] a [〜#〜]オブジェクトがリクエストを受信すると、オブジェクトはリクエスト自体を処理するか、リクエストを2番目のオブジェクトに渡して、作業を行います。オブジェクトがリクエストを渡すことにした場合、オブジェクトはリクエストを処理する責任を2番目のオブジェクトに転送したと言います。

または、簡単な疑似例として、何かがobject1にリクエストを送信します。次に、object1は要求とそれ自体をobject2(デリゲート)に転送します。 object2は要求を処理し、いくつかの作業を行います。 (注:上記のリンクは良い例です)

15

デリゲートは、メソッドを参照できるオブジェクトです。したがって、デリゲートを作成すると、メソッドへの参照を保持できるオブジェクトが作成されます。さらに、この参照を通じてメソッドを呼び出すことができます。したがって、デリゲートは、参照するメソッドを呼び出すことができます。デリゲートの主な利点は、メソッドの呼び出しを指定できることですが、実際に呼び出されるメソッドはコンパイル時ではなく実行時に決定されます。

シンプルなデリゲート

Declaration of delegate:
delegate-modifier delegate return-type delegate-name(parameters)
Implementation of delegate:
Delegate-name delegate-object=new Delegate-name(method of class)

http://knowpacific.wordpress.com/2012/01/26/delegate/

4

デリゲートは、コマンドパターンの単純化された実装について考えてください。

4

ここで、デリゲート、マルチキャストデリゲート、およびそれらの使用法について説明します。デリゲートは、オブジェクトでメソッド参照を保持するタイプです。また、タイプセーフな関数ポインターとも呼ばれます。デリゲートは、メソッドシグネチャを定義する型であると言えます。

デリゲートをインスタンス化すると、互換性のあるシグネチャを持つ任意のメソッドにそのインスタンスを関連付けることができます。デリゲートインスタンスを介してメソッドを呼び出す(または呼び出す)ことができます。デリゲートは、メソッドを引数として他のメソッドに渡すために使用されます。イベントハンドラは、デリゲートを介して呼び出されるメソッドにすぎません。デリゲートを使用する利点は、呼び出し元からのメソッドの呼び出しをカプセル化することです。デリゲートを効果的に使用すると、非同期でメソッドを呼び出すために使用されるアプリケーションのパフォーマンスが向上します。デリゲートのいくつかのプロパティがあります

Delegates are like C++ function pointers but are type safe.
Delegates allow methods to be passed as parameters.
Delegates can be used to define callback methods.
Delegates can be chained together; for example, multiple methods can be called on a single event.
Methods do not have to match the delegate signature exactly.

パブリックデリゲートtype_of_delegate delegate_name()//宣言

You can use delegates without parameters or with parameter list
If you are referring to the method with some data type then the delegate which you are declaring should be in the same format. This is why it is referred to as type safe function pointer. Here I am giving an example with String.

次の例は、デリゲート操作を示しています。

    namespace MyDelegate
    {
        class Program
        {
            private delegate void Show(string s);


            // Create a method for a delegate.
            public static void MyDelegateMethod(string me

ssage)
        {
            System.Console.WriteLine(message);
        }

        static void Main(string[] args)
        {
            Show p = MyDelegateMethod;
            p("My Delegate");
            p.Invoke("My Delegate");
            System.Console.ReadLine();
        }
    }
}

マルチキャストデリゲートとは

複数のメソッドの参照を保持するデリゲートです。マルチキャストデリゲートには、voidを返すメソッドのみが含まれている必要があります。そうでない場合、ランタイム例外が発生します。

 delegate void MyMulticastDelegate(int i, string s);
 Class Class2
 {
  static void MyFirstDelegateMethod(int i, string s)
  {
    Console.WriteLine("My First Method");
  }

  static void MySecondDelegateMethod(int i, string s)
  {
    Console.WriteLine("My Second Method");
  }

  static void Main(string[] args)
  {
    MyMulticastDelegate Method= new MyMulticastDelegate(MyFirstDelegateMethod);
    Method+= new MyMulticastDelegate (MySecondDelegateMethod);
    Method(1,"Hi");             // Calling 2 Methodscalled
    Method-= new MyMulticastDelegate (MyFirstDelegateMethod);
    Method(2,"Hi");             //Only 2nd Method calling
  }
}

ここでは、+ =演算子を使用してデリゲートが追加され、-=演算子を使用して削除されます。

デリゲート型は、.NET FrameworkのDelegateクラスから派生しています。デリゲートタイプは封印されており、派生できません。インスタンス化されたデリゲートはオブジェクトであるため、パラメータとして渡すか、プロパティに割り当てることができます。これにより、メソッドはパラメータとしてデリゲートを受け入れ、後でデリゲートを呼び出すことができます。これは非同期コールバックとして知られています。

2
Jom George

Delegateパターンの優れた説明と実用的な実装は、Googleコレクションにあります Forwarding Classes(また、Decoratorパターン)。

1
Carl

デリゲートは、関数へのポインターを表すオブジェクトです。ただし、次の点で通常の関数ポインターではありません。

1)オブジェクト指向ですか

2)タイプセーフです。つまり、メソッドを指すことしかできず、指している生のメモリアドレスを読み取ることはできません

3)強く型付けされています。署名に一致するメソッドのみを指すことができます。

4)同時に複数のメソッドを指すことができます。

1
Water Cooler v2

イベント通信では、送信者はイベントを処理するオブジェクトを認識しません。デリゲートは、メソッドの参照を保持するタイプです。デリゲートには署名があり、その署名に一致するメソッドへの参照を保持しているため、デリゲートはタイプセーフな関数ポインタに似ています。

button1.Click + = new System.EventHandler(button1_Click)System.EventHandlerはここでデリゲートとして宣言されています。

実行時に呼び出すコードがわからない場合にデリゲートが使用されるため、その時点でデリゲートはイベントの処理に使用されます

http://msdn.Microsoft.com/en-us/library/ms173171(v = vs.80).aspx

1
Yogesh

デリゲートオブジェクトは、そのオブジェクトで何かが発生したときに別のオブジェクトが参照するオブジェクトです。たとえば、あなたの車に何かが起こった場合、修理担当者があなたの代理人になります。あなたはあなたの修理人のところに行き、あなたに車を修理するように彼に頼みます(ただし、車を自分で修理することを好む人もいますが、その場合、彼らは自分の車の代理人です)。

1
user2199128

デリゲートは主にイベントで使用されます。

必要性は:

プログラムを実行するときにコードを実行したくない場合。プログラムを実行した後、イベントが発生するたびにそのコードを実行します。

例:

  1. Console application-コードは、プログラムの実行時にのみ実行できます。 (Mainメソッド内に記述)
  2. Windowsアプリケーション(ユーザーインターフェイスプログラミング)-プログラムの実行後にボタンをクリックすると、コードを実行できます。

これは彼らが言うことであり、コンパイル時にどのメソッドが呼び出されるかわかりません。実行時、つまりボタンをクリックするときのみ知っています。

デリゲートなしでは、ユーザーインターフェイスプログラミングはできません。ユーザーがbuttonをクリックするイベントを作成するたびにコードを実行しているため、テキストボックスに入力する、ドロップダウンリスト項目を選択するなど...

1
shathar khan

デリゲートは、タスクが委任される対象です。委任の主な目的は、コードを分離し、柔軟性と再利用性を高めることです。

プログラミング、具体的にはオブジェクト指向プログラミングでは、これは、何らかの作業を行うためにメソッドが呼び出されると、それが参照を持つ別のオブジェクトのメソッドに作業を渡すことを意味します。オブジェクトが定義済みのメソッドセットに準拠している限り、参照は任意のオブジェクトを指すことができます。 「インターフェイスへのプログラミング」と呼びます(具体的なクラス実装へのプログラミングとは対照的です)。インターフェイスは基本的に汎用テンプレートであり、実装はありません。それは単にレシピ、メソッドのセット、前提条件、および事後条件(ルール)を意味します。

簡単な例:

_SomeInterface
{
   public void doSomething();
}


SomeImplementation implements SomeInterface
{
   public void doSomething()
   {
      System.err.println("Was it good for you?");
   }

}


SomeCaller
{
   public void doIt(SomeInterface someInterface)
   {
      someInterface.doSomething();
   }
}
_

doIt()が渡される型は具体的ではなく、インターフェースであるため抽象的であるため、SomeCallerのコードを変更することなく、いつでも好きな実装を使用できます。 Javaの世界では、これは特定のインターフェースを介してサービスとして自分自身を広告するオブジェクト)を呼び出すサービスパラダイムで表現されることが多く、その後サービスはデリゲートを呼び出しますサービスのメソッドは、粗粒度タスク(makePayment()、createNewUser()など)として名前が付けられていますが、内部的には、デリゲートのタイプがインターフェイスであるため、委任を通じて適切に機能する場合は多くのことを行います具体的な実装の代わりに。

_SomeService
{
    SomeInterface someImplementation = ... // assign here
    SomeOtherInterface someOtherImplementation = ... // okay, let's add a second

    public void doSomeWork()
    {
         someImplementation.doSomething();
         someOtherImplementation.doSomethingElse();
    }
}
_

(N.B .:実装がどのように割り当てられるかは、このスレッドの範囲外です。制御の制御の反転と依存性の注入。)

0
Aquarelle