2011-01-09 14 views
17

entiendo que una declaración de un delegado es algo como esto:En .NET, ¿cuál es la implementación interna de un delegado?

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

Sin embargo, tiene que haber más en juego. El propósito del delegado es proporcionar un puntero a un método, y para hacerlo encapsula la referencia al método en el delegado.

¿Qué tipo de estructura tiene esta referencia (internamente en el delegado)? También entiendo que puede encapsular una referencia a múltiples métodos en un delegado. ¿Esto significa que hay una matriz en el delegado que los contiene?

Además, ¿qué métodos se definen en el delegado, etc. Lo que realmente está sucediendo cuando se declara un delegado con el escueto:

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

?

EDIT: Algunas aclaraciones. Cuando declara un delegado, el compilador automáticamente crea una clase sellada que hereda de System.MulticastDelegate por usted. Puede ver esto si mira su conjunto con ildasm. Esta ordenado. Básicamente, con una declaración, obtendrá una nueva generación generada para usted en tiempo de compilación, y tiene toda la funcionalidad que necesita.

+8

Puede comprobar mucho con reflector. Faltan algunas partes porque requieren tiempo de ejecución mágico. Pero aún verá la mayoría de los contenidos de delegados únicos y multidifusión. – CodesInChaos

Respuesta

8

Todos los delegados heredan del tipo System.Delegate que tienen un Target y Method. Más precisamente heredan de System.MultiCastDelegate que hereda de System.Delegate.

+2

Gracias! Eso es más o menos exactamente lo que estaba buscando. Me siento tonto por no encontrar eso yo mismo. Parece que no puedo encontrar cómo el delegado tiene múltiples referencias. Tiene un objetivo y un método, pero estos no se parecen a las colecciones. . . ¿Que me estoy perdiendo aqui? – richard

+0

@Richard DesLonde, falta [System.MulticastDelegate] (http://msdn.microsoft.com/en-us/library/system.multicastdelegate.aspx), de lo que todos los delegados heredan. He actualizado mi respuesta para mayor claridad. –

+2

No implementan, heredan. – Ani

18

Internamente es un tipo de referencia, bastante similar a una clase. Transcrito se ve así:

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) {} 
} 

Salí de la implementaciones de estos miembros de vacío, que en realidad se asignan al código en el CLR. El compilador genera dinámicamente las firmas de método, según la firma de la declaración del delegado. Tenga en cuenta los argumentos xey. El compilador JIT ayuda a llamar al constructor, usando la sintaxis + = o - =, conoce la dirección de memoria del método de destino del delegado. El compilador generó automáticamente el valor de argumento target, dependiendo de si el método de destino era estático o no. Los dos argumentos se asignan a las propiedades Delegado (Destino) y Destino (Multidifusión). La instancia de la clase base real puede ser Delegate o MulticastDelegate, dependiendo de cuántos objetivos se suscribieron.

Mucha salsa secreta pasando aquí.

+0

cosas buenas. ¿Puedes explicar la sobrecarga involucrada con una invocación de delegado? En particular, frente a una llamada a un método virtual. – Ani

+2

Difícil de decir, el depurador está * muy * de mal humor sobre la depuración de este código. Ciertamente hay gastos generales, no es una simple llamada a un método virtual. Afaict, llama al método jitted Invoke() que luego realiza una llamada indirecta a un procesador que masajea el marco de la pila y llama al invocador correcto, dependiendo de si es un delegado o un delegado de multidifusión. Este último necesita repetir la lista de invocación. Es bastante barato cuando lo perfilé (nanosegundos) pero ciertamente no es tan barato como una simple llamada a un método. –

+0

Gracias Hans. El material interno es muy útil e interesante. – richard

Cuestiones relacionadas