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が失敗すると静的メンバが呼び出される。不思議な実装だな。