Une astuce volée à Jon Skeet
Si certains d’entre vous trouvent pénible le fait de devoir s’assurer qu’un évènement est non null avant de le lancer, voici une idée :
Profitez de la contravariance sur les delegates et initialisez votre event de la sorte :
public event MyEventHandler MyEvent = delegate{};
Ca vous permettra d’être sûr qu’il y a au moins un handler lorsque vous voudrez déclencher MyEvent
, et vous n’aurez donc plus besoin d’écrire par exemple :
if(MyEvent != null) { MyEvent(this, new MyEventHandler(someParam)); }
Vous pourrez directement lancer l’événement sans tester :
MyEvent(this, new MyEventHandler(someParam));
Notez que le handler (inutile) ajouté via le variable initializer à l’event ne pourra plus être retiré, ce qui peut ici être vu comme une sécurité. Cependant, l’avantage de cette astuce est à relativiser :
- Il y a un coût (négligeable la plupart du temps) au niveau des performances.
- Il est parfois plus judicieux d’écrire une méthode chargée d’encapsuler le test de non nullité, et qui pourra souvent être invoquée plus simplement que l’événement lui-même.
Par exemple :
private void FirePropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }
A l’appel, on se retrouve avec :
FirePropertyChanged("Firstname");
Contre :
PropertyChanged(this, new PropertyChangedEventArgs("Firstname"));
Source : C# in Depth: What you need to master C# 2 and 3, de Jon Skeet.
Qu’est-ce qui a le coût le plus important: un test de nullité comme avec la fonction ou l’exécution d’un delegate vide?
J’imagine que ça doit être à peu près similaire, et dans ce cas je préfère utiliser la fonction, qui comme tu le dis rend le code plus concis.
Le test est moins coûteux qu’une invocation de delegate, mais on parle là d’une différence de l’ordre de la dizaine de nanosecondes… Autant oublier cet aspect, et se concentrer sur ce qui compte : lisibilité, concision, évolutivité, etc.
Je pense que l’astuce peut-être utilisée lorsqu’un event n’est déclenché qu’à partir d’une seule méthode de la classe.
!!!! sympa :) Je me fais souvent ch*** à faire le test de nullité car j’ai la flemme de faire la méthode « FirePropertyChanged » (et je duplique d’autres choses).
J’imagine bien que la différence est insignifiante :) Et comme je l’ai dit, quitte à se concentrer sur la lisibilité & co, je maintiens mon opinion sur la fonction.
Mais comme tu dis, pas besoin de s’embêter à créer une nouvelle fonction s’il n’y a qu’un seul appel, et autant utiliser alors cette astuce.
Sinon je me l’achèterais bien ce bouquin, j’avais déjà hésité il y a quelques temps…