Josh Smithの記事「Model-View-ViewModelデザインパターンを使用したWPFアプリ」、具体的にはRelayCommand
(図3)の実装例を検討してください。(この質問については、記事全体を読む必要はありません。)
一般的に、実装は優れていると思いますが、のイベントCanExecuteChanged
へのサブスクリプションの委任について質問があります。州のドキュメント:CommandManager
RequerySuggested
RequerySuggested
このイベントは静的であるため、弱参照としてのみハンドラーを保持します。このイベントをリッスンするオブジェクトは、ガベージコレクションを回避するために、イベントハンドラーへの強力な参照を保持する必要があります。これは、プライベートフィールドを用意し、このイベントにアタッチする前または後にハンドラーを値として割り当てることで実現できます。
しかし、のサンプル実装はRelayCommand
、サブスクライブされたハンドラーに対してそのようなものを維持していません。
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
- これにより、弱参照が
RelayCommand
クライアントにリークされ、ユーザーがライブ参照RelayCommand
の実装を理解してCanExecuteChanged
維持する必要がありますか? もしそうなら、例えば、加入者
RelayCommand
の潜在的な時期尚早のGCを軽減するために、の実装を次のようなものに変更することは理にかなっていますか?CanExecuteChanged
// This event never actually fires. It's purely lifetime mgm't. private event EventHandler canExecChangedRef; public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; this.canExecChangedRef += value; } remove { this.canExecChangedRef -= value; CommandManager.RequerySuggested -= value; } }