Busqué en los archivos y encontré muchas preguntas sobre qué es el remitente y por qué debería usar el patrón, pero no vi nada sobre un evento personalizado y tipo si es remitente.Crear eventos personalizados: ¿remitente de objeto o remitente con tipo?
Digamos que estoy creando una clase personalizada llamada Subscription e implementa ISubscription y tengo algunos eventos args llamados SubscriptionEventArgs. Si la Suscripción tuvo un evento llamado Modificado, ¿qué pasa con la firma del evento Modificada (ISubscription remitente, SubscriptionEventArgs e)?
un poco de código para ayudar a impulsar la pregunta:
public class SubscriptionEventArgs : EventArgs
{
// guts of event args go here
}
public interface ISubscription
{
event Action<ISubscription, SubscriptionEventArgs> Changed;
}
public class Subscription : ISubscription
{
public event Action<ISubscription, SubscriptionEventArgs> Changed;
private void OnChanged(SubscriptionEventArgs e)
{
if (Changed!= null)
{
Changed(this, e);
}
}
}
Si sólo desprecian el uso de la acción en lugar de "manejador de sucesos", entonces se podría hacer lo mismo, pero con una costumbre genérico "manejador de sucesos".
public delegate void EventHandler<TSender, TEventArgs>(TSender sender, TEventArgs e);
public class SubscriptionEventArgs : EventArgs
{
// guts of event args go here
}
public interface ISubscription
{
event EventHandler<ISubscription, SubscriptionEventArgs> Changed;
}
public class Subscription : ISubscription
{
public event EventHandler<ISubscription, SubscriptionEventArgs> Changed;
private void OnChanged(SubscriptionEventArgs e)
{
if (Changed!= null)
{
Changed(this, e);
}
}
}
En respuesta a la solicitud de Hans para un controlador de eventos de muestra:
public class SubscriptionCollection
{
// what is actually holding the subscriptions is not really relevant to the question
private List<ISubscription> _subscriptions;
public SubscriptionCollection()
{
_subscriptions = new List<ISubscription>();
}
public void Add(ISubscription subscription)
{
subscription.Changed += new EventHandler<ISubscription, SubscriptionEventArgs>(Subscription_Changed);
_subscriptions.Add(subscription);
}
private void Subscription_Changed(ISubscription sender, SubscriptionEventArgs e)
{
// Now when the subscription changed event is being handled by the collection
// I don't have to look up the subscription in the list by some key and I don't
// have to cast sender to the correct type because the event handler was typed
// correctly from the beginning.
}
}
La búsqueda de la suscripción en la lista puede parecer trivial, pero lo que si estoy trabajando con grandes conjuntos de datos y nuevos volúmenes de datos llegan a la aplicación a través de una transmisión en tiempo real. El costo de tener que parar y obtener una referencia de una lista o seguir los pasos de un casting no tiene sentido. Nos dieron genéricos en 2.0 para resolver ese problema, así que no entiendo por qué no obtuvimos un gestor de eventos genérico también y esto me llevó a preguntar qué pasa con un controlador de eventos genérico.
me gustaría el segundo bloque mucho más si se agregó un "donde TEventArgs: EventArgs". –
Solo un consejo, pero si usa IObservable en lugar de ISubscription para su tipo de interfaz, creo que estaría siguiendo un patrón de diseño nombrando un poco mejor, y puede ser un poco más claro a simple vista lo que está sucediendo. –