La razón es el rendimiento (de hecho, esa es mi mejor estimación). Los eventos y los delegados están hechos con mucha magia de compilación, cosas que no pueden ser replicadas por el simple código C#. Pero debajo hay algo como esto:
Un delegado es una clase generada por el compilador que hereda de la clase MulticastDelegate
, que a su vez deriva de la clase Delegate
. Tenga en cuenta que estas dos clases son mágicas y usted no puede heredarlas usted mismo (bueno, tal vez sí, pero no podrá usarlas muy bien).
Un evento sin embargo se implementa algo como esto:
private MyEventDelegateClass __cgbe_MyEvent; // Compiler generated backing field
public event MyEventDelegateClass MyEvent
{
add
{
this.__cgbe_MyEvent = (MyEventDelegateClass)Delegate.Combine(this.__cgbe_MyEvent, value);
}
remove
{
this.__cgbe_MyEvent = (MyEventDelegateClass)Delegate.Remove(this.__cgbe_MyEvent, value);
}
get
{
return this.__cgbe_MyEvent;
}
}
bien, así que esto no es verdadero código (ni es exactamente la forma en que es en la vida real), pero debe darle una idea de lo que está pasando
El punto es que el campo de respaldo inicialmente es realmente nulo. De esta forma, no hay gastos generales para crear una instancia de MyEventDelegateClass
al crear su objeto. Y es por eso que debes verificar null antes de invocar. Más adelante, cuando los manejadores se agregan/eliminan, se crea una instancia de MyEventDelegateClass
y se asigna al campo. Y cuando se elimina el último controlador, esta instancia también se pierde y el campo de respaldo se restablece a nulo nuevamente.
Este es el principio de "usted no paga por lo que no usa". Mientras no uses el evento, no habrá gastos generales para él. Sin memoria extra, sin ciclos de CPU adicionales.
Si un delegado es nulo, ¿cómo lo usaría para comprobarlo? Es como llamar a la puerta de la habitación de su hijo y preguntarle si está allí, y esperar un "No" de él si no lo hace. – BoltClock
No es solo una lista de funciones, sino más bien una lista de llamadas a métodos diferibles (incluidos los parámetros y el objeto al que está asociado el método). –
Vea [esta pregunta] (http://stackoverflow.com/questions/170907/is-there-a-downside-to-adding-an-anonymous-empty-delegate-on-event-declaration) para una forma de hacer las comprobaciones nulas son innecesarias (a costa de ciclos de CPU adicionales). –