dynamic

System.Dynamic.DynamicObjectについて

メンバ
 GetDynamicMemberNames : デバッグ用。メンバ名を列挙する。
 GetMetaObject : DynamicMetaObjectを取り出す。DynamicMetaObjectがdynamicのもろもろの動作をしてくれるようだ。
DynamicObjectの場合はそのもろもろの動作をDynamicObjectのメソッドをオーバーライドして記述する。
そうするとDynamicMetaObjectがDynamicObjectのメソッドを呼び出してくれる形らしい。

オーバーライド出来るメソッドは以下のような感じ
*C#から呼び出せる
 TryBinaryOperation : d + d2
 TryConvert : (Hoge)d
 TryGetIndex : d[0]
 TryGetMember : d.Hoge
 TryInvoke : d()
 TryInvokeMember : d.Hoge()
 TrySetIndex : d[0] = hoge
 TrySetMember : d.Hoge = hoge
 TryUnaryOperation : d++
*C#から呼び出せない
 TryCreateInstance
 TryDeleteIndex
 TryDeleteMember

右のように書くと、対応するTry〜が呼び出されるので、引数に渡されたメンバ名を使って処理をしてやる。
そのメンバがないとかで呼び出せないときはfalseを返せばいい。

C#の文法上存在しないようなのは呼び出せないが、オブジェクトに直接カッコを書くd()は認められている。
d.Hoge()と書くと、TryInvokeMemberをしようとするが、それが見つからない場合は
d.HogeをGetMemberして、Getしたものを()でInvokeしようとする。
駄目だった場合は実行時例外になる。

DynamicObjectの場合、ToString()のようなobjectのメンバはdynamicより優先される。
DynamicObjectで動的なToStringメソッドを呼び出したいならToStringをオーバーライドして動的なのを呼び出すことになる。newで再定義してもいい。GetTypeはnewで再定義してやる。
objectのメンバでなく、新しく静的に追加したメンバならdynamicの方が優先される。dynamicが失敗すると静的メンバが呼び出される。不思議な実装だな。