événements .NET - bloquer les abonnés de souscrire à un événement
-
21-09-2019 - |
Question
Disons que j'ai une interface « processeur », l'exposition d'un événement - OnProcess. Habituellement, les implementors font le traitement. Ainsi, je peux en toute sécurité sur cet événement abonne et assurez-vous qu'il sera tiré. Mais un processeur ne fait pas le traitement - donc je veux éviter aux abonnés de Subscibe sur elle. Puis-je faire cela? En d'autres termes dans le code ci-dessous je veux la dernière ligne de lancer une exception:
var emptyProcessor = new EmptyProcessor();
emptyProcessor.OnProcess += event_handler; // This line should throw an exception.
La solution
class EmptyProcessor : IProcessor {
[Obsolete("EmptyProcessor.OnProcess should not be directly accessed", true)]
public event EventHandler OnProcess {
add { throw new NotImplementedException(" :( "); }
remove { }
}
}
Dans ce cas, le paramètre sur true
obsolète provoque une exception à la compilation. donc:
EmptyProcessor processor1 = new EmptyProcessor();
IProcessor processor2 = new EmptyProcessor();
processor1.OnProcess += handler; // <-- compile-time error
processor2.OnProcess += handler; // <-- run-time error
Autres conseils
Vous pouvez la mettre en œuvre des méthodes add
/ de remove
personnalisés, mais je crois que cela est une mauvaise pratique.
Regardez, vous avez une interface , contrat à mettre en œuvre par les différentes classes.
OnProcess
fait partie du présent contrat et n'est pas spécial en aucune façon.
On utilise généralement des interfaces quand elle veut travailler avec des classes différentes sous le même ensemble d'opérations . Interfaces vous permettent de code comme ceci:
IProcessor proc = GetProcessorAnyhow ();
proc.DoSomething ();
sans le savoir type concret au type de compilation.
Cependant, avec votre approche,
IProcessor proc = GetProcessorAnyhow ();
proc.OnProcess += (sender, e) => { };
peut échouer sans aucune raison apparente, bien qu'il ressemble à un code tout à fait légitime.
Assurez-vous que le mauvais code semble mal.
Vous avez peut-être fait l'une des erreurs de conception suivantes:
- Mettre
OnProcess
enIProcessor
alors il ne peut pas être chaque contrat de processeur ; - Fait
EmptyProcessor
mettre en œuvreIProcessor
, alors qu'en réalité il ne peut pas satisfaire le contrat .