Creo que conceptualmente entiendo a los delegados de C #, sin embargo, estoy luchando por encontrar un ejemplo del mundo real donde puedan ser útiles. ¿Puede proporcionar algunas respuestas que detallen cómo se utilizaron los delegados de C # en aplicaciones reales y qué problemas le permitieron solucionar?
16
Respuestas:
El código GUI usa delegados para manejar eventos, como clics de botones, movimientos de ventanas. Usar el delegado le permite tener una función llamada cada vez que ocurre el evento. Un ejemplo sería vincular una función que guarda datos a un botón "Guardar" en la interfaz. Cuando se hace clic en el botón, está configurado para ejecutar la función que guarda los datos. Es útil en la programación de la GUI porque todo su programa podría estar esperando que el usuario haga algo y usted no tiene forma de saber qué hará primero. El uso de delegados permite que la funcionalidad de su programa se conecte a la interfaz de usuario de tal manera que el usuario pueda hacer las cosas de la forma que desee.
fuente
Linq usa
Func<T>
yAction<T>
delega por todo el lugar como parámetros.Estos le permiten usar expresiones lambda como parámetros y definen la acción a tomar como parte de la lista de parámetros.
fuente
Prácticamente cualquier cosa que use el Patrón de Observador probablemente implementaría delegados.
Lea la descripción y probablemente imaginará algunos escenarios en los que los usaría. El manejo de eventos GUI es un ejemplo común.
fuente
Los delegados son muy útiles en la programación asincrónica.
Tienes una clase que hace cosas de forma asincrónica y tiene una devolución de llamada. Puede hacer que se invoque el método delegado al devolver la llamada, y la implementación de su clase hará la lógica descrita en su método delegado.
fuente
Los delegados son particularmente útiles como una solución para el agujero en el patrón del medio . Esencialmente, hay muchos casos en los que desea incluir un conjunto único de instrucciones dentro de un conjunto común de instrucciones. Es particularmente difícil si las instrucciones antes y después del bit único necesitan compartir el estado. Con los delegados, puede pasar un delegado a una función. La función ejecuta el bit anterior, ejecuta el delegado y luego ejecuta el bit posterior.
fuente
En los "viejos tiempos" de los lenguajes que no son OOP como Fortran y C, fue increíblemente útil poder hacer que una subrutina recibiera un argumento que apuntaba a una función. Por ejemplo, la
qsort
función funciona con una función de comparación proporcionada por el usuario. Existen numerosas subrutinas para resolver ecuaciones diferenciales ordinarias o para optimizar funciones, y todas toman punteros de función como argumentos.En los sistemas de ventanas, todo tipo de devoluciones de llamada siguen el mismo patrón.
En Lisp, incluso en los primeros días, había algo llamado un "argumento funcional" o FUNARG, que no solo era una función, sino que también contenía un contexto de almacenamiento donde podía recordar e interactuar con parte del mundo exterior.
Esta misma necesidad existe en los lenguajes OOP, excepto cuando pasa la dirección de una función, también tiene que pasar la dirección del objeto de la cual la función es un método. Eso son dos cosas que tienes que pasar. Entonces, un delegado es solo eso, y permite que se siga utilizando ese buen patrón antiguo.
fuente
Aquí hay un ejemplo simple que muestra cuán útiles pueden ser los delegados para crear código simple que siga el principio DRY. También le permite mantener el código extremadamente cerca de donde se necesita.
Aquí hay un ejemplo del mundo real de la ventaja que brindan los delegados.
fuente
Mi primer encuentro con los delegados fue buscar una actualización del programa (formularios Windows C # 3.5) descargando un archivo de mi sitio web, pero para evitar que la actualización verificara el bloqueo de todo el programa, utilicé un delegado y un hilo para hacerlo de forma asincrónica.
fuente
He visto implementaciones interesantes del patrón de estrategia que usa delegados de manera efectiva. (es decir, la estrategia es un delegado)
El que estaba buscando era para encontrar rutas donde el algoritmo para encontrar la ruta era un delegado que podía (re) asignarse en tiempo de ejecución para que se pudieran usar diferentes algoritmos (BFS vs A * etc.)
fuente
Muchos de los patrones clásicos de GoF se pueden implementar con delegados: por ejemplo, el patrón de comando, el patrón de visitante, el patrón de estrategia, el patrón de fábrica y el patrón de observador a menudo se pueden implementar con un delegado simple. A veces, una clase es mejor (por ejemplo, cuando un comando necesita un nombre o un objeto de estrategia necesita ser serializado), pero en la mayoría de los casos, usar
Action<...>
oFunc<...>
es mucho más elegante que crear una interfaz dedicada de un método.fuente