如何动态调用动态对象的方法? [英] How can I dynamically call a method on a dynamic object?
问题描述
当我想动态调用静态定义(静态中的在编译时确定的意义上,而不是在类级成员的意义上)的方法上的任何对象在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屋!