3

インターフェイスを動的に実装する DynamicObject ベースのクラスがあります (TryGet* および TryInvoke* を使用)。リフレクションを使用して実装するメソッドを呼び出したい。問題は、TargetException (オブジェクトがターゲット タイプと一致しない) をスローすることです。

私が言ったように、それは動的であるため、一連の接続を介して呼び出しをテキストとして別のプログラムに転送し、リフレクションを使用して宛先メソッドを呼び出します。基本的にプロキシクラスです。メソッド名はコンパイル時に (インターフェースのために) 認識されますが、外部から呼び出されます。

typeof(ITelescope).GetMethod(Console.ReadLine()).Invoke(prox,null);

ITelescope はインターフェイスでproxあり、動的オブジェクトです。

4

3 に答える 3

4

残念ながら、動的に定義されたメソッドはリフレクション経由では利用できません。これの一部は、それらが本当に動的であるという事実によるものです.ANYメソッドが有効な動的オブジェクトを持つことができるため、そのシナリオでリフレクションが適切に機能する方法はありません. (つまり、何がGetMethods()返されるでしょうか?)

dynamicオブジェクトが動的オブジェクトである場合、通常はそれを に割り当て、動的バインディングを使用してメソッド呼び出しを取得するのが最善の方法です。

dynamic yourObj = prox;
yourObj.Unpark();
于 2012-10-22T17:07:43.960 に答える
3

リフレクションで動的メソッドを呼び出すことはできませんが、動的メソッドを実行する DynamicObject のTryGet.../TryInvoke...メソッドを呼び出すことはできます...

dynamic obj = new MyDyn();
Console.WriteLine(obj.Text);

string methodName = "YourDynamicMethod";                    

var p1 = new ParameterModifier(2);
p1[0] = false; p1[1] = true;

var args = new object[] { new MemberBinder(methodName, true), null };

var res = typeof(DynamicObject).InvokeMember(
    "TryGetMember",
    BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
    null,
    obj,
    args,
    new ParameterModifier[] { p1 },
    null,
    null);

var result = args[1];

public class MyDyn : DynamicObject
{
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = "#" + binder.Name + "#";
        return true;
    }
}

public class MemberBinder : GetMemberBinder
{
    public MemberBinder(string name, bool ignoreCase) : base(name, ignoreCase)
    {
    }

    public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
    {
        throw new NotImplementedException();
    }
}
于 2012-10-22T18:39:58.430 に答える
3

dynamic キーワードを使用するだけでなく、もう少しメタ的なことをしようとしている場合は、私が作成した ImpromptuInterface (apache ライセンス、nugetにあります) に興味があるかもしれません。

動的オブジェクトと一致するインターフェイスがあるように見えるので、Impromptu を使用して動的オブジェクトをインターフェイスでラップできます。impromptu は静的にインターフェイスを持つオブジェクトを動的に発行し、そのインターフェイスからの呼び出しを動的オブジェクトに転送しますdlrを使用します。

ITelescope iprox = Impromptu.ActLike(prox);
prox.Unpark();

または、リフレクションと同様に、文字列名で動的オブジェクトのメソッドを呼び出したいだけの場合は、動的に dlr 呼び出しを呼び出す、メソッドのようなリフレクションもたくさんあります。インターフェイス方式よりは効率が悪いですが、リフレクションよりは効率的です。

Impromptu.InvokeMember(prox,"Unpark");
于 2012-10-22T17:35:41.980 に答える