He leído que un tipo de referencia contiene la referencia a un objeto real que puede almacenarse en el montón administrado. Cuando un método se "asigna" a una variable de referencia de delegado, ¿a qué memoria apunta la referencia? ¿Qué tiene que ver este bloque de memoria con el código de función real?¿Qué señala un delegado?
Respuesta
Tomemos un ejemplo sencillo aparte:
using System;
class Program
{
delegate bool MyFilter(int x);
bool IsOdd(int x)
{
return x % 2 == 1;
}
static void Main()
{
MyFilter f = new Program().IsOdd;
Console.WriteLine(f(5));
}
}
¿Qué hace el compilador? Vamos a empezar con esta línea:
delegate bool MyFilter(int x);
El compilador genera un tipo que se ve algo como esto:
class MyFilter : MulticastDelegate
{
public MyFilter(Object thisRef, IntPtr method);
public bool Invoke(int x);
// BeginInvoke(), EndInvoke() - Let's ignore those
}
El tipo myFilter tiene un constructor que acepta dos parámetros: un IntPtr que el cuerpo del método invocar, y un Objeto sobre el cual este método debería ser invocado. El método Invoke() en el tipo de MyFilter invoca al delegado real.
Ahora, veamos qué sucede en el método Main(). El compilador reescribirla algo como esto:
static void Main()
{
MyFilter f = new MyFilter(new Program(), addressof(Program.IsOdd));
Console.WriteLine(f.Invoke(5));
}
Por supuesto, AddressOf no es un operador real C#, pero se puede imaginar que devuelve la dirección del cuerpo para el método pasado de entrada. Además, no discutí otros temas relacionados con los delegados, como el encadenamiento (esta es una característica proporcionada por la clase base de MulticastDelegate), pero espero haber abordado su pregunta.
Para resumir, la referencia de delegado apunta a un objeto que implementa un método Invoke que coincide con la firma del delegado. El objeto rastrea el puntero al método que necesita invocarse, y también el objeto de destino en el que invocar el método (a menos que el método sea estático).
En realidad, hay dos tipos de delegados, Delegate y MulticastDelegate. Estas son clases abstractas heredadas en una instancia real de delegate
. Recomendaría leer estas clases ya que tienen muchos más detalles (precisos) de los que he explicado aquí, pero para la versión corta:
Si bien no estoy 100% seguro de cómo funciona exactamente la implementación, la forma más fácil de pensar en un objeto Delegate
tiene un object
y MethodInfo
, que es el tipo de reflejo para un método en particular. La razón por la cual el tipo Delegate
es abstracto es porque el método Invoke
depende de los parámetros del método.
mismo modo, MulticastDelegate
contener múltiples Delegate
objetos, que cada punto a un individuo combinación object
/MethodInfo
. Esto permite que el sistema event
, donde se dispara un solo event
se llame a múltiples métodos.
Volviendo a los detalles de implementación, cuando se define un delegado, se crea una clase heredada de MulticastDelegate
con un método Invoke
, también la object
puede haber null
para los métodos estáticos.
Además de esto, usted tiene los detalles sobre cómo pasan los objetos MulticastDelegate
entre las invocaciones, pero probablemente ya cometí algunos errores en esta publicación, así que lo dejo así.
Sin dar una respuesta demasiado complicada, apunta (hace referencia) al bloque de memoria real donde se almacena el método.
Un delegado realmente contiene dos direcciones: la dirección del método y la dirección del objeto. Esto es bastante interesante, y varias patentes relacionadas con delegados fueron otorgadas a Heljsberg http://www.google.com/patents/US6185728
Es altamente eficiente. En un interview, Heljsberg señaló que puede ser más eficiente que el envío VTBL (ya que es un puntero directo a una función). En los casos más simples, es literalmente una llamada indirecta. por ejemplo,
jmp *%eax
En general, se necesita 4 instructions to execute a delegate.
- 1. ¿Cuándo Windows señala un identificador de proceso?
- 2. ¿Qué es Delegado y Métodos de delegado
- 3. ¿Qué es un delegado de C++?
- 4. ¿Por qué un delegado sin parámetros compila?
- 5. cúmulo iPhone Mapa Kit señala
- 6. Cómo convertir un delegado a un delegado idéntico?
- 7. ¿Debo anclar un delegado anónimo?
- 8. Varios UIAlertViews para un delegado
- 9. ¿Por qué se declara este evento con un delegado anónimo?
- 10. ¿Por qué el puntero "this" es nulo en un delegado?
- 11. ¿Por qué un delegado de .NET no se declara estático?
- 12. ¿por qué el delegado debe ser estático?
- 13. ¿Qué constituye la 'creación de delegado redundante'?
- 14. establecer un delegado para UIWebView
- 15. delegado para un objeto singleton
- 16. ¿Hay un delegado que no sea un delegado de multidifusión en C#?
- 17. NSTextFieldCell Delegado?
- 18. ¿Por qué la consola señala que he cambiado mi prototipo antes que yo?
- 19. Compruebe si un objeto es un delegado
- 20. Comprobación de un MethodInfo contra un delegado
- 21. ¿Puede un delegado tener un parámetro opcional?
- 22. Usando un delegado para administrar dos UIActionSheets
- 23. ¿Cómo declaras un delegado predicado en línea?
- 24. ¿Tiene un NSURLConnection conservar su delegado?
- 25. Python: select() no señala todas las entradas de la tubería
- 26. delegado resultados
- 27. __unsafe_unretained por un delegado no construirá
- 28. ¿Qué es un delegado en Cocoa y por qué debería usarlo?
- 29. ¿Cómo se señala una aplicación sin matarla en Linux?
- 30. ¿Por qué ReadDirectoryChangesW, con solo el filtro FILE_NOTIFY_CHANGE_LAST_WRITE, señala más de un evento en la edición de archivos?
No es exactamente la respuesta que está buscando, pero esta publicación podría proporcionar alguna información sobre los delegados http://stackoverflow.com/questions/527489/how-delegates-work-in-the-background –