20

デリゲートの宣言は次のようなものであることを理解しています。

public delegate int PerformCalculation(int x, int y);

ただし、さらに多くのことが行われている必要があります。デリゲートの目的は、メソッドへのポインターを提供することと、メソッドへの参照をデリゲートにカプセル化することです。

この参照はどのような構造で (デリゲートの内部で) 保持されていますか? また、複数のメソッドへの参照をデリゲートにカプセル化できることも理解しています。これは、これらを保持するデリゲートに配列があることを意味しますか?

また、デリゲートで定義されているメソッドなど。デリゲートを簡潔に宣言すると実際に何が起こるか:

public delegate int PerformCalculation(int x, int y);

?

編集:いくつかの明確化。デリゲートを宣言すると、コンパイラは System.MulticastDelegate から継承するシールクラスを自動的に作成します。これは、アセンブリをildasmで見るとわかります。このすっきり。基本的に、1 つのステートメントで、コンパイル時に生成された新しいクラス全体を取得し、必要なすべての機能を備えています。

4

2 に答える 2

19

内部的にはクラスによく似た参照型です。転写すると次のようになります。

public /* delegate */ class PerformCalculation : MulticastDelegate {
    public PerformCalculation(object target, IntPtr method) {}
    public virtual void Invoke(int x, int y) {}
    public virtual IAsyncResult BeginInvoke(int x, int y, AsyncCallback callback, object state) {}
    public virtual void EndInvoke(IAsyncResult result) {}
}

これらのメンバーの実装は空のままにしました。実際には CLR のコードにマップされています。コンパイラは、デリゲート宣言のシグネチャに応じて、メソッド シグネチャを動的に生成します。x および y 引数に注意してください。JIT コンパイラは、+= または -= 構文を使用して呼び出されるコンストラクターを取得するのに役立ち、デリゲート ターゲット メソッドのメモリ アドレスを認識します。コンパイラは、ターゲット メソッドが静的かどうかに応じて、ターゲット引数値を自動的に生成しました。2 つの引数は、(Multicast)Delegate.Target および Method プロパティにマップされます。実際の基底クラス インスタンスは、サブスクライブされたターゲットの数に応じて、Delegate または MulticastDelegate のいずれかになります。

ここには秘伝のタレがたっぷり。

于 2011-01-09T21:44:31.480 に答える
9

すべてのデリゲートは、 TargetMethodを保持するSystem.Delegate型から継承します。より正確には、から継承するSystem.MultiCastDelegateから継承します。System.Delegate

于 2011-01-09T21:30:10.997 に答える