2009-10-29 16 views
12

¿Es posible en C# conectar un evento a otro, por lo que la emisión del primer evento emitirá el segundo? La única forma en que puedo ver es crear una función de stub que emitirá un segundo evento y conectar el primer evento a esta función. Compilador no quieren conectar un evento a otro o evento a la función anonymouse/lambda que llama a otro evento:¿Suscribirse evento al evento en C#?

class Ui { public event EventHandler OnClick; } 
class Logic { public event EventHandler OnExit; } 
var ui = new Ui(); 
var logic = new Logic(); 
ui.OnClick += logic.OnExit; // Not working. 
ui.OnClick += (a, b) => logic.OnExit; // Not working either :(. 

Tal vez sea un poco decorador, o un poco de magia negro que permite a eventos de la cadena sin funciones del trozo?

Respuesta

9

No se puede hacer esto, porque por lo general no se puede hacer nada para un evento desde fuera del objeto que lo posee, excepto para agregar y quitar controladores. En particular, no puede enumerar los manejadores registrados existentes, y no puede subirlo. En su caso, "copiar" el evento es esencialmente lo mismo disfrazado, y le permitiría eludir esta restricción; por lo tanto, no está permitido.

Consulte this recent answer para obtener una explicación más detallada de por qué las cosas son como son, simplemente no tengo ganas de volver a escribir todo aquí.

para su caso particular, si usted es dueño de ambas clases, la solución consiste en que colaboren en concreto - hacer Ui ser conscientes de la Logic instancia asociada, y añadir controladores de eventos a Logic.OnClick en Ui.OnClick.add aplicación. Por supuesto, esto introduce el acoplamiento; puede reducirlo hasta cierto punto mediante el uso de interfaces más genéricas, pero no puede deshacerse de él por completo.

Como nota al pie, OnClick no es un buen nombre para un evento .NET. La guía de nomenclatura común dice que debe ser simplemente Click (y OnClick debe ser el nombre de un método protected virtual que lo plantea).

+2

Este acoplamiento de introducción - que dice que es todo^_ ^. – grigoryvp

+0

Ese es precisamente el punto. La lista de manejadores es privada para el objeto que posee el evento, por diseño. La razón es que solo el objeto debe controlar cuándo y cómo se invocan los controladores. Es una encapsulación básica. Si desea romper la encapsulación, deberá proporcionarle una eclosión especial, y sus clases deben ser conscientes de ello, de ahí el acoplamiento. Lo que estás pidiendo realmente no es diferente de "¿puedo acceder al campo privado de una de mis clases de otra?". –

+0

Entonces, básicamente, todo lo que tengo que hacer es mover el código de suscripción a una clase que posee el segundo evento? :) – grigoryvp

3

Puede hacer esto ocultando el evento subyacente para Logic y luego controlar las llamadas a Agregar/Eliminar que requieren un parámetro UI.

public class UI { 
    public EventHandler OnClick; 
} 
public class Logic { 
    private event EventHandler _onExit; 
    public void AddOnExit(UI ui, EventHandler e) { 
    ui.OnClick += e; 
    _onExit += e; 
    } 
    public void RemoveOnExit(UI ui, EventHandler e) { 
    ui.OnClick -= e; 
    _onExit -= e; 
    } 
} 
+1

En su ejemplo, no está tratando de vincular dos eventos del mismo objeto: está intentando vincular eventos de emparejamiento de pares entre dos objetos diferentes. –

+0

@Pavel, ah OK. La misma lógica funciona entre dos objetos si están conectados de otra manera. Pero sí, un poco diferente a mi ejemplo, udpate – JaredPar

Cuestiones relacionadas