9

動的に生成されたメソッドから内部メソッドを呼び出そうとしています。il コードは単純です: ldarg_0、callvirt、ret.

メソッドの実行は、内部メソッドが定義されている型を読み込めないことを示す TypeLoadException で失敗します。

考えてみると、動的メソッドのホスト アセンブリは、メソッドの宣言型アセンブリのフレンドではないため、これは論理的に思えます。

ただし、Delegate.CreateDelegate が機能するのと同じように、動的メソッドがまだ機能することを期待していました。結局のところ、内部メソッドの MethodInfo を取得できたので、アクセス許可の障壁は背後にあります。

とにかく、問題は「動的に生成されたメソッドから内部メソッドを呼び出すことは可能ですか?」ということです。

ありがとう。

編集:

問題を示す簡単なコード サンプルを次に示します。

using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;

namespace A
{
  internal class Data
  {
    internal string String { get; set; }
  }

  public static class Program
  {
    public static void Main()
    {
      Expression<Func<Data, string>> expr = x => x.String;
      var getterInfo = ((PropertyInfo)((MemberExpression)expr.Body).Member).GetGetMethod(true);
      var getter1 = (Func<Data, string>)Delegate.CreateDelegate(typeof(Func<Data, string>), getterInfo);
      var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) });
      var gen = dm.GetILGenerator();
      gen.Emit(OpCodes.Ldarg_0);
      gen.Emit(OpCodes.Castclass, typeof(Data));
      gen.Emit(OpCodes.Callvirt, getterInfo);
      gen.Emit(OpCodes.Ret);
      var getter2 = (Func<object, object>)dm.CreateDelegate(typeof(Func<object, object>));

      var data = new Data() { String = "Hello" };
      var str1 = getter1(data);
      var str2 = getter2(data);
    }
  }
}

コードでは、2 つのオープン インスタンス デリゲートを作成して、Data.String インスタンス プロパティにアクセスします。

  • Delegate.CreateDelegate を使用して safe getter1 と入力します
  • DynamicMethod を使用して安全でない getter2 を入力します

Delegate.CreateDelegate によって作成されたタイプ セーフなデリゲートは機能しますが、DynamicMethod を使用するデリゲートは TypeLoadException で失敗します。

ゲッターが作成されるコンテキストは一般的ではないため、タイプセーフなアプローチを取りたくないことに注意してください。もちろん、この問題は解決できますが、問題はプリンシパルの問題です。Delegate.CreateDelegate が成功するのに DynamicMethod が失敗するのはなぜですか?

4

1 に答える 1

6

可視性チェックをスキップすると機能します。

この行を変更

var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }, true);

msdnを参照してください: (特に、すべてのルールを含む表)。

これは、コンストラクターの doco からのものです。

RestrictedSkipVisibility 型: System.Boolean 動的メソッドの MSIL によってアクセスされる型とメンバーの JIT 可視性チェックをスキップする場合は true。次の制限があります。これらの型とメンバーを含むアセンブリの信頼レベルは、信頼レベル以下である必要があります。動的メソッドを発行するコール スタックのレベル。それ以外の場合は false。

于 2009-11-22T11:15:12.037 に答える