JITの参照範囲チェックをスキップ?
id:siokoshou:20070505 のコードにもう一つ問題がありました。
DynamicMethod dm = new DynamicMethod( "Compare", typeof( int ), new Type[] { t, t }, this.GetType() );
(tは typeof( T ))
として、動的メソッドを FastPropertyComparer
けれど、これだと他モジュールで自前で定義したクラスの public な getアクセサにアクセスできませんでした。System.MethodAccessException なんて例外が飛んできました。
DateTimeではどう?ってDayの比較を試してみると、これはOK。
もういっちょUriのSchemeで試してみたけど、こちらもOK。
ワケワカラン。
十分なアクセス許可があれば、動的メソッドはジャスト イン タイム (JIT: Just-In-Time) の参照範囲チェックをスキップし、そのモジュール内で宣言されている型のプライベート データにアクセスできます。
DynamicMethodの説明にこう記述があるんで、参照範囲チェックってやつにひっかかってるんだろうなぁ。プライベートデータではないんだけど…。
DynamicMethod dm = new DynamicMethod( "Compare", typeof( int ), new Type[] { t, t }, this.GetType(), true );
のように参照範囲チェックをスキップするか、
DynamicMethod dm = new DynamicMethod( "Compare", typeof( int ), new Type[] { t, t }, t );
のように、直接対象の型に比較メソッドを生成してやればすんなり動きました。
DynamicMethodの説明を読む限り、この動作はおかしいような気がするんですが…。それとも何か理解が間違ってるのかなぁ・・・。
(追記)
もうちょっと試してみました。
getアクセサを通して最終的にアクセスするフィールドがpublicならどうなる?とやってみると、やっぱり例外。
どうもドキュメントと動作が違うような気がするけど、とにかくモジュール越えで引っかかるようですね。
(ちょっとあせって正反対の誤報を流してしまったのは内緒)