2

次のクラスが与えられます。

class SomeBuilder<T>
{
    public static object Build(int index)
    {
        ...
    }
}

class SomeHelper
{
    public object GetBuildObj(object value)
    {
        var valuetype = value.GetType();
        var methodinfo = typeof(SomeBuilder<>).MakeGenericType(valuetype).GetMethod("Build");
        var handler = SomeDynamicHelper.GetMethodInvoker(methodinfo);
        var result = hander(null, new object[]{1});
    }
}

SomeBuilder はジェネリック型だったので、正しくするには MakeGenericType() を呼び出す必要があります。

値に「class person」などの通常の型を渡すと、すべてが機能します。問題ありません。

しかし、新しい { id=1 } のような匿名型を渡すと、ハンドラーが正常に作成されました。しかし、この動的ハンドラーを呼び出すと、次のメッセージで MethodAccessException が発生しました。

"method "SomeDynamicHelper.(System.Object, System.Objec[])"メソッドへのアクセスに"SomeBuilder'1<<>f__AnonymousType0'1<System.Int32>>.Build(int)"失敗しました。

任意の助けをいただければ幸いです、thx。

ところで、SomeDynamicHelper に興味がある場合は、以下を参照してください。

http://www.codeproject.com/Articles/14593/A-General-Fast-Method-Invoker

編集1:

私はこのようにメインで呼び出しを行いました:

static void Main(string[] args)
{
    // pass a normal class, this will be fine
    var value = new Person { id = 1};
    new SomeHelper().GetBuildObj(value);  

    // pass a anonymous type
    var value = new { id = 1};
    new SomeHelper().GetBuildObj(value);  // oops, got a exception here!
}

編集2:

コメントに基づいて、コードを変更しました:

class SomeHelper
{
    public object GetBuildObj(object value)
    {
        //this time i do not use the value, but create a new inner value:
        var valuenew = new { id = 1 };
        var valuetype = valuenew.GetType();
        var methodinfo = typeof(SomeBuilder<>).MakeGenericType(valuetype).GetMethod("Build");
        var handler = SomeDynamicHelper.GetMethodInvoker(methodinfo);
        var result = hander(null, new object[]{1});
    }
}

さて、今回も例外ではありませんが...残念ながら新しい問題が発生しました...新しい問題については、新しいスレッドを作成する必要があるかもしれません。

皆さん、お気遣いありがとうございます。

編集3:

こんにちは、いくつか掘り下げた後、私もいくつかの有用な情報を見つけました。たとえば、 SomeDynamicHelper.GetMethodInvoker() コードは次のようになります。

DynamicMethod dynamicMethod = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object), typeof(object[]) }, methodInfo.DeclaringType.Module);

これは、メソッドを動的に作成するためにここで使用したコアです。このコンテキストでは、SomeHelper および SomeBuilder と同じアセンブリで匿名型を宣言する必要があります。しかし、申告ができない場合はどうすればよいのでしょうか。

OK、最後のパラメーター (skipVisibility) を true に設定して DynamicMethod() を呼び出すことができます!

これが同じ問題を抱えている他の人に役立つことを願っています:)

4

3 に答える 3

2

「メソッド "SomeDynamicHelper.(System.Object, System.Objec[])" はメソッド "SomeBuilder'1<<>f__AnonymousType0'1>.Build(int)」にアクセスしようとしています

これから、動的メソッドが Build と呼ばれる internal\private メソッドを実行しようとしていることがわかります。

(匿名型は、新しく生成されたクラスに保持されます)

InternalVisibleTo匿名型アセンブリを(手動またはインターセプトで)書き換えることができ、型とメソッドが内部でプライベートではない場合にのみ役立つため、追加が常に役立つとは限りません。

動的メソッドでは、メソッドをタイプ\モジュールにバインドし、可視性チェックをスキップできますが、これは指定されたモジュールのプライベートメンバーにアクセスするのに役立ちます。アクセスしようとしているタイプが別のアセンブリにあり、タイプ\メソッドである場合プライベートで何もできません。

よくほとんど。アセンブリに注入し、呼び出された「秘密の」属性があり、IgnoreAccessChecksToバインドされたモジュールに加えて、可視性をスキップする可能性があります。

于 2016-05-08T17:28:13.227 に答える