Considérez la référence de l'article de Josh Smith sur les applications WPF avec le modèle de conception Modèle-Vue-ModèleVue, en particulier l'implémentation d'exemple d'un RelayCommand
(dans la Figure 3). (Pas besoin de lire l'intégralité de l'article pour cette question.)
En général, je pense que l'implémentation est excellente, mais j'ai une question sur la délégation des abonnements de CanExecuteChanged
à l'événement RequerySuggested
du CommandManager
. La documentation sur RequerySuggested
indique :
Comme cet événement est statique, il ne conservera le gestionnaire que sous forme de référence faible. Les objets qui écoutent cet événement doivent conserver une référence forte à leur gestionnaire d'événement pour éviter qu'il ne soit ramassé par le ramasse-miettes. Cela peut être réalisé en ayant un champ privé et en assignant la variable du gestionnaire en valeur avant ou après avoir attaché cet événement.
Pourtant, l'implémentation d'exemple de RelayCommand
ne maintient pas une telle référence au gestionnaire abonné :
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
- Cela fuit-il la référence faible jusqu'au client de
RelayCommand
, nécessitant que l'utilisateur deRelayCommand
comprenne l'implémentation deCanExecuteChanged
et maintienne lui-même une référence vivante ? -
Si tel est le cas, est-ce logique, par exemple, de modifier l'implémentation de
RelayCommand
pour être quelque chose comme ce qui suit pour atténuer le risque de collecte prématurée des déchets du souscripteur deCanExecuteChanged
:// Cet événement ne se produit jamais réellement. C'est purement pour la gestion du cycle de vie. private event EventHandler canExecChangedRef; public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; this.canExecChangedRef += value; } remove { this.canExecChangedRef -= value; CommandManager.RequerySuggested -= value; } }