La documentación para EventHandler<TEventArgs> dice:
El segundo parámetro es un tipo derivado de EventArgs y proporciona los campos o propiedades necesarios para contener los datos del evento.
y parece ser generalmente recomendado a lo largo de la documentación de .Net.
Sin embargo, resulta que puedo hacer lo siguiente que funciona bien:
public event EventHandler<int> Panned;e invoque el controlador de eventos como:
int value = 10; if (Panned != null) { Panned(this, value); }y del lado del observador:
subject.Panned += (sender, e) => { Console.WriteLine(e); }; Para mí, esto parece mejor que ensuciar el código con pequeñas clases que heredan de EventArgs o tener un EventArgs genérico como lo propone ¿Tiene .NET un EventArgs<T> incorporado?
Entonces, ¿por qué es necesario que herede el argumento genérico EventHandler de EventArgs ?
Si todo lo que necesita hacer es pasar un int al controlador, entonces lo que está haciendo está bien.
Solía ser el caso ( antes de .NET 4.5) que el argumento de tipo EventHandler TEventArgs estaba obligado a heredar de EventArgs pero ya no:
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);El hecho de que MS eliminó la restricción debería indicarle que estaban siendo demasiado estrictos y que lo que está haciendo está bien.
En el caso de que necesite pasar un tipo complejo al controlador, también podría heredar EventArgs por razones de polimorfismo. Además, el miembro EventArgs.Empty es útil.
Esto es solo una convención. De hecho, ni siquiera tiene que usar el delegado genérico EventHandler<> . Podrías tener:
public event Action SomeEvent; public void OnAction() { var a = this.SomeEvent; if (a != null) { a(); } } Por supuesto, la convención está ahí por una razón. Hasta donde yo sé, todos los eventos estándar de .NET siguen el patrón de usar un delegado que devuelve el vacío que toma un parámetro de object y un segundo parámetro de EventArgs o un tipo derivado. Esto facilita el uso de estos eventos sin tener que consultar la documentación cada vez.
¿Esto funcionara?...
class Program { public static event Func<int> SomeEvent; static void Main(string[] args) { SomeEvent += () => 7; SomeEvent += () => 8; var a = SomeEvent(); Console.WriteLine(a); } } Lo probé: lo hace! Por supuesto, es muy extraño tener un evento en el que el delegado tenga un valor devuelto, porque no es obvio qué valor del controlador se devolverá a la persona que llama si hay varios controladores adjuntos. En el ejemplo anterior, resulta que 8 está escrito en la consola.
Interesante pero, sospecho, inútil ;-)
No creo que sea sensato tener un tipo de delegado que no regrese vacío, como en mi ejemplo. Sin embargo, podría considerar usar un delegado cuyos parámetros sean tipos de valor (estructuras, no clases) por motivos de rendimiento. Podría ser posible usar eventos sin incurrir en la sanción de recolección de elementos no utilizados de asignar objetos EventArgs en el montón.