DLR 返回类型
我需要 DLR 的帮助。我正在实现 IDynamicMetaObjectProvider 和 DynamicMetaObject,但在获取预期返回类型时遇到一些问题。我在元对象中覆盖 BindInvokeMember,我可以看到所有参数类型,但看不到返回类型。如果可能的话,有人知道我该如何实现吗?我知道返回类型是动态的,但是如果您调用的东西依赖于返回类型怎么办?我不知道在 DynamicMetaObject 中执行哪个操作,除非我知道消费者期望的返回类型。
更新二
我无法在此处粘贴我的实际代码,因为它调用了各种工作内容。下面是一些示例动态目标代码。
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();
}
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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于返回某些内容的标准二进制文件,返回类型几乎总是对象(get、set、操作等)。否则对于标准绑定(例如DeleteMember)来说它是无效的。
您还可以在运行时从传入绑定器上的 ReturnType 属性获取预期的返回类型。
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.
看起来返回类型至少是我使用的 beta 版本不知道...
我试图使用 DLR 制作 ap/invoke 示例,但似乎这是不可能的,除非您传入预期的返回类型作为参数我最终这样做了:\ 在我看来,这似乎是一个限制......希望将来能得到解决。
It appears the return type at least is the beta i was using is not know...
I was trying to make a p/invoke example using the DLR but it seems like this is not possible unless you pass in the expected return type as a parameter which I ended up doing :\ This seems to me like a limitation... Hopefully it will be addressed in the future.