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.
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();
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With