如何动态调用动态对象的方法? [英] How can I dynamically call a method on a dynamic object?

查看:141
本文介绍了如何动态调用动态对象的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我想动态调用静态定义(静态中的在编译时确定的意义上,而不是在类级成员的意义上)的方法上的任何对象在C#中,我可以使用反射来得到一个处理的方法,并调用它:

When I want to dynamically call a statically-defined ("statically" in the sense of "determined at compile-time", not in the sense of "class-level member") method on any object in C#, I can use reflection to get a handle to that method and invoke it:

typeof(Foo).GetMethod("Bar").Invoke(foo, new object[] { /* params */ });

不过,对象所做的动态由 DynamicObject 继承来(不确定)实例方法调用使用 TryInvokeMember 响应,动态方法的类响应不通过反射暴露,原因很明显。这意味着,我不能让一个方法处理的方法,应该由 TryInvokeMember 进行回应。

However, objects made dynamic by inheriting from DynamicObject respond to (undefined) instance method calls using TryInvokeMember, and the dynamic methods the class responds to are not exposed through reflection, for obvious reasons. This means that I can't get a method handle for a method that should be responded to by TryInvokeMember.

因此​​讽刺的是,在我看来,你不能动态调用上的动态对象动态方法一样容易,你可以在一个非调用定义的方法动态对象。

So ironically, it seems to me that you can't dynamically call a dynamic method on a dynamic object as easily as you can call a defined method on a non-dynamic object.

我认为叫 TryInvokeMember 直接,但第一个参数必须是一个 InvokeMemberBinder ,一个实例抽象类。我觉得,如果我要实现一个类来调用动态对象的动态方法,我一定是做错了什么。

I've considered calling TryInvokeMember directly, but the first argument must be an instance of an InvokeMemberBinder, an abstract class. I feel that if I have to implement a class to call a dynamic method on a dynamic object, I must be doing something wrong.

我怎么能说上一个动态对象由它的名称的方法,知道目标类的没有的实现,而且它应该要回答使用 TryInvokeMember

How can I call a method on a dynamic object by its name, knowing that the target class does not implement it and that it should be responded to using TryInvokeMember?

推荐答案

一去了解它模仿什么动态对象的方法调用C#编译器的输出方式。这需要一堆标注类型的使用 [EditorBrowsable(EditorBrowsableState.Never)] Microsoft.CSharp.RuntimeBinder 命名空间,所以他们不会在智能感知可见。不用说,这似乎不是一个支持的方案,所以使用它需要您自担风险!

One way to go about it is to mimic what the C# compiler outputs for method invocations on dynamic objects. This requires the usage of a bunch of types marked in the Microsoft.CSharp.RuntimeBinder namespace, so they will not be visible in Intellisense. Needless to say, this doesn't seem like a supported scenario, so use it at your own risk!

这code调用动态酒吧方法,无需从 DynamicObject :

This code calls the dynamic Bar method without any arguments on an instance of a class derived from DynamicObject:

dynamic dynamicObject = new DerivedFromDynamicObject();
var callSiteBinder = Binder.InvokeMember(CSharpBinderFlags.None, "Bar", Enumerable.Empty<Type>(), typeof(Program),
    new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
var callSite = CallSite<Action<CallSite, object>>.Create(callSiteBinder);
callSite.Target(callSite, dynamicObject);

的博客文章的这个对调用点和粘合剂更血淋淋的细节。

This blog post and this one have more gory details on call sites and binders.

这篇关于如何动态调用动态对象的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆