2009-04-24 15 views
6

Cuando implemento un evento en Visual Studio, Resharper tiene la amabilidad de ofrecerme la creación de un invocador de eventos. Solía ​​hacer esto a mano en el pasado, y mis invocators siempre se veía asíInvocadores de eventos en C#

private void InvokePropertyChanged(PropertyChangedEventArgs e) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, e); 
     } 
    } 

pero el invocador creado por ReSharper tiene este aspecto (limpiado un poco a mano)

private void InvokePropertyChanged(PropertyChangedEventArgs e) 
    { 
     PropertyChangedEventHandler changed = PropertyChanged; 

     if (changed != null) 
     { 
      changed(this, e); 
     } 
    } 

Haga lo las personas en jetbrains saben algo sobre C# yo no? ¿Hay alguna ventaja técnica para tener la variable local, o es solo un artefacto de tener que generar automáticamente el código?

Respuesta

8

Sí. Saben que la cantidad de suscriptores a un evento puede cambiar entre el "si" y la llamada al controlador de eventos. Lo capturan en un local, donde ya no cambia.

+0

son u seguro de eso? no los dos "apuntan" a la misma lista de invocación? – BFree

+1

No necesariamente. La lista completa podría cambiar, en general. Tenga en cuenta que ReSharper es una herramienta "general". Usted parece estar asumiendo que lo único que sucede con el evento es + = y - =. Tal vez sí, tal vez no, pero el modo "ReSharper" cubre todas las bases. –

+1

En realidad, la cantidad de suscriptores no importa, eso es responsabilidad del delegado. Sin embargo, es importante el hecho de que el delegado sea nulo si no hay suscriptores. Si no hay suscriptores, el campo es nulo. Copia una referencia nula, por lo tanto, si se agrega un suscriptor después, si no lo ve, no fallará. –

5

Creo que John Saunders probablemente tenga la mejor respuesta.

Para el registro, ya no escribo "Invocators". Tengo métodos de extensión que lo hacen por mí, y acabo de llamar al PropertyChanged.Fire(this, "propName");

Ver this article para obtener más información.

+2

Oye, eso es genial. Me alegro de haber preguntado. – MichaC

+0

¿No elimina por completo la posibilidad de sobrescribir el comportamiento del invocador de eventos aquí? No tienes posibilidad de cambiar el comportamiento en las clases derivadas. – bberger

+0

@bberger Supongo, pero hacer eso es raro. SI necesita un comportamiento extensible, entonces hágalo a la manera de la vieja escuela. –

1

Esto es solo un problema para el multihilo. Esto lo protege en un entorno multiproceso.

Por ejemplo, tomemos este escenario:

if (PropertyChanged != null) // PropertyChanged has one subscriber here 
{ 

Ahora, un segundo hilo cancele la suscripción aquí, modificando el controlador de eventos ....

PropertyChanged(this, e); // This is no longer valid! 
}