4

最近は、C# WPF アプリで Reactive Extensions をほぼ独占的に使用しています。イベント ハンドラーの追加と削除はアンチ パターンであり、F# イベントが IObservable を実装するという事実に完全に嫉妬しています。

C# 開発者を支援するために、RX 関係者は以下の方法を提供しています (およびさまざまなタイプの安全性を持つ他のいくつかの方法)。

public static 
IObservable<EventPattern<TEventArgs>> 
FromEventPattern<TDelegate, TEventArgs>
    ( Action<TDelegate> addHandler
    , Action<TDelegate> removeHandler
)
where TEventArgs : EventArgs

http://msdn.microsoft.com/en-us/library/hh211731(v=vs.103).aspx

私はそのようにそれを使用します

var movingEvents = Observable.FromEventPattern<MouseEventHandler, 
    MouseEventArgs>(h => this.MouseMove += h, h => this.MouseMove -= h);

しかし、これは面倒です。できるようになりたいのは

var movingEvents = h.MouseMoveObserver();

そしてそれで終わります。このような拡張メソッドは次のようになります

IObservable<MouseEventArgs> MouseMoveObserver(this Canvas This){
    return Observable.FromEventPattern<MouseEventHandler, 
    MouseEventArgs>(h => This.MouseMove += h, h => This.MouseMove -= h); 
}

それはロケット科学ではなく、必要に応じてこれらの拡張メソッドを一度に 1 つずつ追加するライブラリを設定することを検討しています。ただし、リフレクションを介して WPF ライブラリ内のすべてのコントロールを処理し、必要なすべての拡張メソッドを生成する T4 テンプレートをスマート Cookie で作成できると確信しています。私の質問は...

上記のように、イベントをオブザーバブルにマップするコードジェネレーターを書いた人はいますか?私は .Net リフレクションに関してはあまり得意ではありませんが、いくつかのシード コードから始めることができるかもしれません。

4

1 に答える 1

6

FrameworkElement から派生したすべての型を取得するには、次を使用できます。

var typesToDo = from t in Assembly.GetAssembly(typeof(FrameworkElement)).GetTypes()
                where t.IsSubclassOf(typeof(FrameworkElement)) 
                        && t.IsPublic 
                        && t.GetEvents().Any()
                select t;

次にtype.GetEvents()、各タイプのイベントを取得するために使用できます。返される EventInfo を使用すると、名前、型、引数などを確認できます。

一般的なイベントに対処するには、少し余分な作業を行う必要がありますが、それほど多くはありません。

サンプル プログラムを出力例と共にGitHub にアップしました。

一部の出力が適切に機能しないリスクがあります。すべてを試したわけではありません:) すべてがビルドされ、少なくとも一部が正しく機能することを確認しました。

于 2013-02-16T14:58:51.117 に答える