7

DLR の助けが必要です。IDynamicMetaObjectProvider と DynamicMetaObject を実装していますが、予期される戻り値の型を取得する際に問題が発生しています。メタオブジェクトで BindInvokeMember をオーバーライドしています。すべての引数の型を確認できますが、戻り値の型は確認できません。可能であれば、私がそれに到達する方法を知っている人はいますか?戻り値の型が動的であることは知っていますが、呼び出しているものが戻り値の型に依存している場合はどうでしょうか。消費者が期待している戻り値の型がわからない限り、DynamicMetaObject で実行するアクションはわかりません。

アップデート 2

あらゆる種類の作業を呼び出すため、実際のコードをここに貼り付けることはできません。サンプルの動的オブジェクト コードを以下に示します。

public class TestDynamicMetaObject : DynamicMetaObject
{
    public TestDynamicMetaObject(Expression expression, object value)
        : base (expression, BindingRestrictions.Empty, value)
    {
    }

    public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
    {
        Delegate method = new Func<int>(Test);
        return new DynamicMetaObject(
            Expression.Call(method.Method),
            BindingRestrictions.GetInstanceRestriction(Expression,Value),
            Value
        );
    }

    public static int Test()
    {
        return 10;
    }

}
public class TestDynamicObject : IDynamicMetaObjectProvider
{
    DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
    {
        return new TestDynamicMetaObject(parameter, this);
    }
}

使っているところはこちら。

static void Main(string[] args)
{
    try
    {
        dynamic x = new TestDynamicObject();
        int gg= x.Test();
        Console.WriteLine(gg);
    }
    catch (Exception excep)
    {
        Console.WriteLine(excep);
    }
    Console.ReadLine();
}

コンパイラが作成するコードは次のとおりです。

private static void Main(string[] args)
{
    try
    {
        object x = new TestDynamicObject();
        if (<Main>o__SiteContainer0.<>p__Site1 == null)
        {
            <Main>o__SiteContainer0.<>p__Site1 = CallSite<Func<CallSite, object, int>>.Create(new CSharpConvertBinder(typeof(int), CSharpConversionKind.ImplicitConversion, false));
        }
        if (<Main>o__SiteContainer0.<>p__Site2 == null)
        {
            <Main>o__SiteContainer0.<>p__Site2 = CallSite<Func<CallSite, object, object>>.Create(new CSharpInvokeMemberBinder(CSharpCallFlags.None, "Test", typeof(Program), null, new CSharpArgumentInfo[] { new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null) }));
        }
        Console.WriteLine(<Main>o__SiteContainer0.<>p__Site1.Target(<Main>o__SiteContainer0.<>p__Site1, <Main>o__SiteContainer0.<>p__Site2.Target(<Main>o__SiteContainer0.<>p__Site2, x)));
    }
    catch (Exception excep)
    {
        Console.WriteLine(excep);
    }
    Console.ReadLine();
}
4

2 に答える 2

5

何かを返す標準バイナリの場合、戻り値の型はほとんど常にオブジェクト (get、set、operations など) です。それ以外の場合、標準バインディング (たとえば、DeleteMember) では無効です。

受信バインダーの ReturnType プロパティから、実行時に予想される戻り値の型を取得することもできます。

于 2009-09-01T01:54:58.137 に答える
0

少なくともリターンタイプは、私が使用していたベータ版がわからないようです...

DLRを使用してap/invokeの例を作成しようとしましたが、最終的に実行したパラメーターとして期待収益タイプを渡さない限り、これは不可能のようです:\これは制限のように思えます...うまくいけば将来的に対処されます。

于 2009-12-11T09:27:38.093 に答える