DataGrid, 脱Reflection(壱)

 WPF4のDataGridで表示される各行(アイテム)は、ItemsSourceプロパティにバインディングされたコレクションのアイテムとバインディングされる。そして、各列の値は、Bindingで指定されたPathを使ってそのアイテムのプロパティから取得される。この「アイテムから指定プロパティの値を取得する」は、どう実装されているかと言えば、やはりというか、当然リフレクションが使われている。このリフレクションでプロパティの値を取得するという処理は、パフォーマンス的にあまりよろしくない。一つや二つであれば無視できるレベルであるんだけど、数が増えれば無視できなくなる。
 例えば、四十個のプロパティとバインディングする行が四万行あるとすれば、リフレクションの呼び出しは、40,000行x40個 = 1,600,000回になる。四十個なんてあるの?と思うが、実際の仕事において、四十個なんてザラである。自分が開発に関わったアプリケーション(Windows.Forms)の中では、最大の列数は百十個超だ。まあ、百個超のプロパティを持つアイテムを万単位でバインディングすると、WPFだのWindows.Formsだの関係なく、メモリがやばい事になるんだけど(こっちはこっちでデータ仮想化というテーマで記事にできるんだけど、本稿とは別の話になる。ぶっちゃけ、データ仮想化の方が大事だったりする)。
 じゃあ、このリフレクションを止めて他の方法にしたいと思っても、リフレクションを使うのはWPFであって、開発者が手を出せない領域であったりする。どうにかならないかと調べたら、TypeDescriptionProvider属性を設定すると、リフレクションよりそちらを優先するらしいという記事があった(正確には、ICustomTypeDescriptorインターフェースのGetPropetiesメソッドが最優先される。このインターフェースが、TypeDescriptionProvider属性クラスと密接に関係する)。この辺り、結構ややこしく、調べるのに時間がかかったけど、
TypeDescriptionProvider
ICustomTypeDescriptor
PropertyDescriptor
この3つを上手く実装すれば、脱リフレクションへの道が開けるかもという事がわかった。

PropertyDescriptorクラスは、プロパティの情報取得、値の設定や取得にも使えるクラス。PropertyDescriptorというクラスそのものは、抽象クラス。抽象クラスなんだけど、こんな記述がある。

通常、abstract メンバーはリフレクションによって実装されます。 リフレクションの詳細については、.NET Framework のリフレクション のトピックを参照してください。

ああ、ということは、PropertyDescriptor含めて、各クラスを継承して自分で実装しないと、意味ないってことですね。
続く。
スポンサーサイト
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0


この記事へのコメント

コメントの投稿

非公開コメント


サイドバー背後固定表示サンプル

当ブログに書かれたソースコードは流用自由です。

バグ、スペルミス等はありうる事です。

ご利用の際は自己責任でお願いしますm(_ _)m