2010-11-12 20 views
10

.NET 2.0 agregó el tipo de delegado genérico EventHandler<TArgs> para simplificar el proceso de escribir eventos personalizados; en lugar de tener que definir una clase EventArgs y su correspondiente delegado (por ejemplo, MyEventArgs y MyEventHandler), solo necesita escribir la clase args.¿Por qué es genérico EventHandler <TArgs> tan infrautilizado?

Teniendo esto en cuenta, ¿por qué este tipo de delegado aparece casi en ninguna parte en .NET Framework? Sé que la mayoría de las API centrales se desarrollaron antes de que se introdujeran los genéricos, pero incluso en partes nuevas del marco como WPF, han optado por definir explícitamente los tipos de delegados; p.ej. RoutedEventHandler en lugar de EventHandler<RoutedEventArgs>.

¿Hay algo intrínsecamente incorrecto con el delegado gestor de eventos genérico? A menudo lo uso y me preocupa que mi código aparezca muy fuera de lugar en comparación con las clases integradas.

+0

Sospecho que la introducción de 'EventHandler ' fue un mal momento. Para el momento en que se introdujo, el otro patrón (delegados explícitamente nombrados) estaba firmemente establecido y comenzar un cambio hacia el tipo de delegado genérico podría haber sido visto como un desastre aún mayor (llevando a los programadores confundidos a preguntar: "¿Qué fue eso? delegar llamado de nuevo? 'FooEventHandler' o' EventHandler '?" _) - Lo que me da curiosidad si el cambio hacia 'IEvent '(introducido por F # y el framework Rx) funcionará. – stakx

+3

WPF se inició en julio de 2003, mucho antes de que estuvieran disponibles los genéricos. Lo mismo ocurre con las formas de Windows, por supuesto. –

Respuesta

7

Sólo un accidente de la historia. Si tuviéramos genéricos en .NET 1, la mayoría de los otros delegados no existirían.

5

No creo que haya nada de malo en ello. Es es utilizado en algunos lugares del marco ... en el evento GeoCoordinateWatcher.Position, solo como un ejemplo al azar.

Es un poco torpe para ver en el código de un nombre de tipo específico como RoutedEventHandler - y como se va a utilizar RoutedEventHandler un mucho en WPF/Silverlight, tal vez por eso MS decidió darle su propio tipo.

2

También podría ser que cuando está escribiendo código de nivel de marco tiende a ser más explícito. Cuando escribe el kit de herramientas y el código de nivel de aplicación, no es así.

1

Lo que sigue es solo mi opinión personal, pero parece (obviamente) razonable para mí; Si observamos de cerca cómo trabajas usando .net y v studio, parece que la notación de tipo genérico parece tener alguna "belleza".

List<string> lst = new List<string>(); 
lst.Add("hello world"); 

Mientras que el código anterior es bastante simple, recto hacia adelante apoyado y bien por el sentido Intelli el manejador de sucesos "apariencia" duerma parece que clara. El soporte por defecto de intelli sugerirá solo el manejador de eventos, no su genérico. Además la notación sólo se ve terrible:

private event EventHandler<MyClass> SomeEvent; 
private event EventHandler<AnotehrClass> OtherEvent; 
privete event EventHandler<MoreClass> MoreEvents; 



Mientras estructura hacia el código que se lee "manejador de sucesos" cada vez y su mente puede conectar a los delegados, por culpa que se utilizan para identificar la relación de tipos por sus nombres .

Por otro lado, también podría haber una explicación menos técnica y lógica:
En primer lugar, siempre obtendrá un objeto remitente en el método de manejo. Si bien esto parece útil a primera vista, siempre se usa cebada.
Además, sus argumentos tienen que derivar de EventArgs que pueden ser molestos o, a veces, imponerse debido al uso de componentes existentes.
Aparte de los genéricos típicos (por ejemplo, IList/List) se pierde la posibilidad de utilizar un tipo más abstracto (como una interfaz) o simplemente un tipo simple (como un doble).
Por último, pero no menos importante, existen las reglas/sugerencias de notación presentadas por microsoft. Para su ejemplo sobre el evento enrutado, la regla podría decir que su tipo está "marcado" como enrutado al tener su nombre con la palabra "Enrutado". Mientras que el nombre del evento en sí mismo dice que el nombre comienza con una "Vista previa".

Como mencioné: esto es solo mi opinión, así que no me culpes;)

+0

El parámetro 'sender' definitivamente tiene sus usos. Se hace efectivo cada vez que tiene el mismo controlador vinculado a eventos en múltiples objetos. Si bien no es útil todo el tiempo, las personas que usan su código esperan que esté disponible. En cuanto al uso de descendientes de 'EventArgs', personalmente creo que promueve la idea de establecer una puerta entre tu código y el del usuario, asegurándote de que nunca les das accidentalmente un objeto mutable que no quieres que modifiquen, etc. Sin embargo, tus comentarios sobre la nomenclatura son definitivamente válidos. Me hace desear que C# tuviera 'typedef' ... –