Compartir a través de


Distinción de delegados y eventos

Anterior

Los desarrolladores que no están familiarizados con la plataforma .NET suelen tener problemas al decidir entre un diseño basado en delegates y un diseño basado en events. La elección de delegados o eventos suele ser difícil, ya que las dos características del lenguaje son similares. Los eventos incluso se crean con compatibilidad de lenguaje para los delegados. Una declaración del controlador de eventos declara un tipo de delegado.

Ambos ofrecen un escenario de unión tardía: habilitan escenarios en los que un componente se comunica llamando a un método que solo se conoce en tiempo de ejecución. Admiten métodos de suscripción individuales y múltiples. Puede que encuentres estos términos referidos como compatibilidad con difusión única y multidifusión. Ambos admiten una sintaxis similar para agregar y quitar controladores. Por último, para generar un evento y llamar a un delegado se usa exactamente la misma sintaxis de llamada de método. Incluso ambos admiten la misma sintaxis del método Invoke() para su uso con el operador ?..

Con todas esas similitudes, es fácil tener problemas para determinar cuándo usar qué.

Escuchar eventos es opcional

La consideración más importante para determinar qué característica de lenguaje usar es si debe haber o no un suscriptor adjunto. Si su código debe llamar al código proporcionado por el suscriptor, debería usar un diseño basado en delegados cuando necesite implementar un callback. Si el código puede completar todo su trabajo sin llamar a ningún suscriptor, debe usar un diseño basado en eventos.

Tenga en cuenta los ejemplos creados durante esta sección. El código que creó mediante List.Sort() debe tener una función de comparador para ordenar correctamente los elementos. Las consultas LINQ deben proporcionarse con delegados para determinar qué elementos se van a devolver. Ambos usaron un diseño creado con delegados.

Considere el evento Progress. Informa del progreso de una tarea. La tarea continúa prosiguiendo si hay o no agentes de escucha. El FileSearcher es otro ejemplo. Seguirá buscando y encontrará todos los archivos que se deseaban, incluso sin tener suscriptores de eventos adjuntos. Los controles de experiencia del usuario siguen funcionando correctamente, incluso cuando no hay suscriptores que escuchen los eventos. Ambos usan diseños basados en eventos.

Los valores devueltos necesitan delegados

Otra consideración es el prototipo de método que desearía para el método delegado. Como has visto, los delegados utilizados para eventos tienen todos un tipo de retorno void. Hay expresiones para crear controladores de eventos que devuelvan información a los orígenes de eventos mediante la modificación de propiedades del objeto de argumento de evento. Aunque estas expresiones funcionan, no son tan naturales como devolver un valor de un método.

Observe que estas dos heurística pueden estar presentes a menudo: si el método delegado devuelve un valor, afecta al algoritmo de alguna manera.

Los eventos tienen invocación privada

Las clases distintas de las que contiene un evento solo pueden agregar y quitar agentes de escucha de eventos; solo la clase que contiene el evento puede invocar el evento. Los eventos suelen ser miembros de clase públicos. En cambio, a menudo los delegados se pasan como parámetros y se almacenan como miembros de clase privada si no están almacenados.

Los escuchadores de eventos suelen tener una vida útil mayor.

El mayor tiempo de vida de los escuchadores de eventos es una justificación un poco más débil. Sin embargo, es posible que los diseños basados en eventos sean más naturales cuando el origen del evento genera eventos durante un largo período de tiempo. Puede ver ejemplos de diseño basado en eventos para controles de experiencia del usuario en muchos sistemas. Una vez suscrito a un evento, el origen del evento puede generar eventos durante toda la vigencia del programa. (Puede cancelar la suscripción de eventos cuando ya no los necesite).

Compare eso con muchos diseños basados en delegados, donde un delegado se usa como un argumento para un método, y el delegado no se usa después de que se devuelva ese método.

Evaluar cuidadosamente

Las consideraciones anteriores no son normas estrictas. En su lugar, representan instrucciones que pueden ayudarle a decidir qué opción es mejor para su uso concreto. Dado que son similares, incluso puedes prototipar ambos y considerar con cuál sería más natural trabajar. Ambos controlan escenarios de enlace en tiempo de ejecución correctamente. Use el que comunique su diseño lo mejor.