How can I dynamically call a method on a dynamic object?
.net, c#, dynamic-language-runtime
Solution
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 `[EditorBrowsable(EditorBrowsableState.Never)]` 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!
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.
Problem
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 */ }); ``` 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. 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. 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`?