2011-02-08 9 views
5

En todo el libro de .NET que he leído, la guía para la implementación de eventos explica que debe crear la subclase EventArgs y usar EventHandler. Busqué más información en http://msdn.microsoft.com/en-us/library/ms229011.aspx, y dice "Use System.EventHandler en lugar de crear nuevos delegados manualmente para usarlos como controladores de eventos". Entiendo que hay razones importantes para usar EventArgs, pero mi pregunta no es "¿Debo hacerlo de esta manera?", Sino "¿Puedo hacerlo de esta manera?".¿Existe una asociación especial entre la clase EventArgs y la palabra clave event?

¿Hay alguna razón por la que no pueda usar un delegado genérico en lugar de un EventHandler con mis eventos? Por ejemplo, si quiero un remitente de tipo fuerte (¿alguien más se molesta por ese object sender?).

Para explicar mejor lo que quiero decir, ¿hay alguna razón para que lo siguiente no funcione?

public class IoC 
{ 
    public AbstractFactory GetAbstractFactory() 
    { 
     var factory = new AbstractFactory(); 
     factory.CreateObject +=()=>new object(); 
     return factory; 
    } 
} 
public class AbstractFactory 
{ 
    public event Func<object> CreateObject; 

    private object OnObjectCreated() 
    { 
     if(CreateObject == null) 
     { 
      throw new Exception("Not injected."); 
     } 
     return CreateObject(); 
    } 


    private object _injectedObject; 
    public object InjectedObject 
    { 
     get 
     { 
      if(_injectedObject == null) 
      { 
       _injectedObject = OnObjectCreated(); 
      } 
      return _injectedObject; 
     } 
    } 
} 
+0

He hecho exactamente esto para implementar algo similar a una colección observable. – asawyer

+0

Tema relacionado: http://stackoverflow.com/questions/4828212/should-eventhandler-always-be-used-for-events/4828233 – CodesInChaos

Respuesta

5

Es solo una convención, y no es un requisito del idioma. Puede usar cualquier tipo de delegado como un evento.

El EventHandler<T> firma estándar tiene algunas ventajas sin embargo:

  1. Se puede extender el parámetro EventArgs. Esto no funcionaría si tuviera un parámetro para cada cosa que desea pasar al controlador de eventos.
  2. un manejador de sucesos que acepta la base de clase EventArgs puede suscribirse a cualquier evento siguiendo la convención
  3. Puede agregar métodos de extensión a EventHandler<T> que aparecen en todos los eventos.
  4. El tipo de devolución es void. Otros tipos de devolución no tienen mucho sentido como eventhandlers.
  5. Estás siguiendo la convención. Seguir la convención suele ser una buena idea, a menos que tenga argumentos convincentes para no hacerlo.
3

Toda la documentación de Microsoft trata sobre el diseño de las bibliotecas de la clase base y/o las pautas de diseño del marco general. Puedes usar cualquier patrón que desees.

Dicho esto, si la gente va a consumir su código, les resultará más familiar si sigue los patrones que usa Microsoft.

0

Hasta donde yo sé, EventHandler y EventArgs son las mejores prácticas, pero no hay nada que impida que use cualquier delegado arbitrario en una declaración de evento. La palabra clave event le otorga la funcionalidad especial de poder + = y - = delegar en el espacio del evento, en lugar de simplemente tener un campo o propiedad del tipo de delegado, que solo aceptará un único delegado (a menos que componga varios delegados) tú mismo).

Advertencia: No estoy seguro de qué ocurre con los delegados con valores devueltos en un espacio de eventos. Supongo que los valores de retorno se descartan, ya que sería difícil manejar delegados múltiples con valores devueltos asignados al evento. Esto requeriría algo de experimentación sin embargo.

+0

Se devuelve el último valor. Pero eso es igual de inútil. –

Cuestiones relacionadas