El propósito de los delegates

Duplicar:

Diferencia entre eventos y delegates y sus respectivas aplicaciones

¿Cuáles son las ventajas de los delegates?

¿Dónde uso delegates?

Me pregunto cuál es el propósito de los delegates. No los he usado tanto y realmente no puedo pensar en algo.

En mis cursos, está escrito que un delegado es un blueprint para todos los métodos que cumplen con su firma.

Además, puede agregar múltiples métodos a un delegado, y luego se ejecutarán uno después del otro en el orden en que se agregaron. Lo cual probablemente solo sea útil para los métodos que afectan las variables locales o los métodos que no devuelven ningún valor.

He leído que C # implementa Eventos como delegates, que está documentado como:

//Summary: Represents the method that will handle an event that has no event data. //Parameters: //sender: The source of the event. //e: An System.EventArgs that contains no event data. [Serializable] [ComVisible(true)] public delegate void EventHandler(object sender, EventArgs e); 

Aún así, es un poco confuso. ¿Alguien puede dar un buen y útil ejemplo de este concepto?

Sí,

Ya casi estás ahí. Un delegado se refiere a un método o función a ser llamado. .NET usa los eventos para decir … cuando alguien presiona este botón, quiero que ejecutes este fragmento de código.

Por ejemplo, en el uso de una aplicación de GPS:

 public delegate void PositionReceivedEventHandler(double latitude, double longitude); 

Esto dice que el método debe tomar dos dobles como las entradas, y devolver el vacío. Cuando llegamos a definir un evento:

 public event PositionReceivedEventHandler PositionReceived; 

Esto significa que el evento PositionRecieved llama a un método con la misma definición que el delegado PositionReceivedEventHandler que definimos. Entonces cuando lo haces

 PositionRecieved += new PositionReceivedEventHandler(method_Name); 

El method_Name debe coincidir con el delegado, de modo que sepamos cómo ejecutar el método y qué parámetros espera. Si utiliza un diseñador de Visual Studio para agregar algunos eventos a un botón, por ejemplo, todo funcionará en un delegado que espera un objeto y un parámetro EventArgs.

Espero que ayude a algunos …

Como notó, un delegado es una forma de crear una firma para una llamada a un método. Hay muchos ejemplos excelentes de usar delegates, pero el que realmente me abrió la mente es este ejemplo.

 public delegate Duck GetDuckDelegate(); public GetDuckDelegate GiveMeTheDuckFactoryMethod(string type) { switch(type) { case "Rubber": return new GetDuckDelegate(CreateRubberDuck); case "Mallard": return new GetDuckDelegate(CreateMallardDuck); default: return new GetDuckDelegate(CreateDefaultDuck); } } public Duck CreateRubberDuck() { return new RubberDuck(); } public Duck CreateMallardDuck() { return new MallardDuck(); } public Duck CreateDefaultDuck() { return new Duck(); } 

Entonces para usarlo

 public static void Main() { var getDuck = GiveMeTheDuckFactoryMethod("Rubber"); var duck = getDuck(); } 

Podría decirse que el patrón Factory sería un mejor método para esto, pero pensé en este ejemplo sobre la marcha y pensé que era el objective de cómo los delegates pueden ser tratados como objetos

Los delegates le permiten pasar métodos en torno a valores similares.

Por ejemplo, .Net tiene un método llamado Array.ForEach que toma un delegado y una matriz, y llama al delegado en cada elemento de la matriz.

Por lo tanto, podrías escribir,

 int[] arr = new int[] { 1, 2, 4, 8, 16, 32, 64 }; Array.ForEach(arr, new Action(Console.WriteLine)); 

Este código llamará a Console.WriteLine para cada número en la matriz.

Hay muchas cosas que puede hacer al hacer funciones que toman delegates, especialmente cuando se combinan con métodos anónimos. Por ejemplo, mira LINQ .

Puedo proporcionarle un ejemplo usando una architecture de aplicación web:

En general, con una aplicación web puede proporcionar un controlador frontal que recibe solicitudes de muchos clientes. Podríamos poner todos nuestros métodos dentro del controlador frontal para tratar con los diferentes tipos de solicitudes de los clientes. Sin embargo, esto se vuelve un poco engorroso. En su lugar, podemos usar delegates para encapsular la funcionalidad de diferentes solicitudes. Nosotros podríamos tener:

  • Delegado de Autenticación
  • Delegado de gestión de usuarios

y así. Por lo tanto, es una manera ordenada de dividir la funcionalidad en fragmentos lógicos: delegates. El marco Struts se basa en esta forma de trabajar (las clases ActionServlet y Action).

Hay muchos artículos excelentes que explican a los delegates: estos son algunos buenos:

Delegados y eventos
C # delegates explicados
Delegados en C #

Muchas personas inicialmente se confunden con la necesidad real de delegates y eventos. Yo fui uno de ellos y me llevó algo de tiempo averiguarlo :-). Recientemente, respondí una consulta similar en los foros de ASP.NET y pensé que sería bueno si creaba una publicación de blog sobre este tema. Aquí estaba la consulta:

“Estaba leyendo un ejemplo en alguna parte de una Clase del Banco que, si se alcanza el saldo mínimo, debe informar al rest de la aplicación que ha alcanzado el valor mínimo, pero no podemos hacerlo simplemente llamando a un método normal, por ejemplo: digamos cuando dedujimos una cierta cantidad del saldo y si se alcanza un mínimo, entonces llame a algún método para tomar alguna medida, estoy totalmente perdido ¿por qué necesitamos delegates y eventos personalizados aquí? ”

Lo que pasa es que en el caso del Banco, definitivamente se puede llamar a un método, pero luego sería una simple progtwigción de procedimientos, necesitamos progtwigción basada en eventos cuando queremos que nuestro código responda a algunos eventos generados por un sistema.

Por ejemplo: piense que Windows OS es un sistema, y ​​estamos escribiendo un código (en cualquier idioma) donde queremos capturar un evento como mouse_click (). Ahora, ¿cómo sabe nuestro progtwig que se ha producido un clic del mouse? Podemos usar código de bajo nivel para ello, pero dado que el sistema operativo ya está manejando el código de bajo nivel, es mejor capturar un evento planteado por el sistema operativo.

En otros términos, en el momento en que mouse_click () ocurre, el SO dispara un evento. Al sistema operativo no le importa quién captura este evento y lo usa, simplemente envía una notificación. Entonces, cualquier código (como el nuestro) puede capturar ese evento y usarlo en consecuencia. Esto nos ahorra mucho tiempo para escribir el código para nosotros mismos. Y otros progtwigs también pueden usar el mismo evento y manejarlo en consecuencia.

Del mismo modo, el sistema bancario puede ser enorme, y muchas otras aplicaciones externas podrían estar accediendo a él. El sistema bancario no sabe cuántas aplicaciones de ese tipo existen que lo necesitan, o dependen de él, y cómo manejarían ciertas situaciones, como cuando el saldo es bajo, por lo que simplemente activa un evento cada vez que se produce un saldo bajo, y este evento puede ser utilizado por cualquier otro código, además del código bancario en sí.

Tenga en cuenta que cada suscriptor de ese evento puede manejar ese evento de forma independiente, por ejemplo. el código bancario puede detener la ejecución de algo si el saldo es bajo, alguna otra aplicación de informes podría enviar un correo electrónico en tal caso, o algún código ATM puede detener una transacción particular y notificar al usuario que el saldo es bajo.

Espero que esto aclare un poco las cosas!

Los delegates, a mi entender, proporcionan una forma de especializar el comportamiento de una clase sin subclasificarla.

Algunas clases tienen un comportamiento genérico complejo, pero todavía están destinadas a ser especializadas. Piense en una clase de ventana en un marco de GUI: una ventana puede hacer mucho por sí misma, pero lo más probable es que todavía desee especializarla de alguna manera. En algunos marcos, esto se hace a través de la herencia. Una forma diferente de hacerlo es con los delegates. Supongamos que desea que suceda algo cuando la ventana cambia de tamaño: su clase de delegates puede implementar un método llamado onWindowResize (siempre que la clase Window lo admita), que se invoca cuando la ventana cambia de tamaño y es responsable de cualquier comportamiento especializado cuando la ventana redimensiona

No voy a discutir los méritos de la delegación sobre la herencia, pero basta con decir que hay muchos que consideran que la delegación es más “limpia” que la herencia.