Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DLR return type

I need some DLR help. I am implementing an IDynamicMetaObjectProvider and DynamicMetaObject but I am having some issues getting the expected return type. I am overiding BindInvokeMember in the metaobject, I can see all the args types but no return type. Anyone know how I get to it if possible? I know the return type is dynamic but what if the thing you are invoking is dependent on a return type. I don't know which action to perform in the DynamicMetaObject unless I know the return type the consumer is expecting.

Update Two

I cant paste my actual code here since it calls all kinds of work stuff. Some sample dynamic object code is below.

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);
    }
}

Here is where I am using.

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();
}

Here is the code that the compiler creates.

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();
}
like image 544
AbdElRaheim Avatar asked Sep 01 '09 00:09

AbdElRaheim


1 Answers

For the standard binaries which return something the return type is almost always object (get, set, operations, etc...). Otherwise it's void for the standard bindings (e.g. DeleteMember).

You can also get the expected return type at runtime from the ReturnType property on the incoming binder.

like image 99
Dino Viehland Avatar answered Oct 17 '22 03:10

Dino Viehland