I just stumbled upon this other thing that I don’t think I know: is it possible to dispatch really dynamically through the DLR, from C#? Let me explain. We know that we can use dynamic in C# 4.0, like so:
dynamic i = 10; // i is now dynamic, but still works like an int: int j = i + 10 // I can call crazy stuff on i, but the compiler doesn't care - // it'll crash at runtime of course i.DoSomethingYouCantReallyDo();
If you haven’t checked out code like this in Reflector, go ahead and do so. You’ll find that the C# compiler generates a rather large amount of code for each “dynamic call site”, which calls into the DLR and instructs it to dispatch the calls (in the case above to the operator + as well as the
DoSomethingYouCantReallyDo method) to the objects. The DLR in turn has a number of fallback mechanisms to try, basically the way dispatch happens in the end depends on the type of object you use. Fair enough. Now, what if I know the name of a method on an object at runtime, but I didn’t know it at design time. Obviously the compiler can’t create clever code for me in that case. Basically, I’d like to do this:
string methodName = "AddValues"; // in reality, retrieve this from somewhere at runtime dynamic o = ... // retrieve dynamic object from somewhere as well // Now call the method with the name 'methodName' on the object o, passing in params x and y o.DispatchDynamically(methodName, x, y);
DispatchDynamically in the last line doesn’t exist – at least I don’t think it does! That’s my question, the thing I don’t currently know – is there a method like this somewhere? I know this is possible when talking to IronPython, for instance. In this case I can use IronPython specific data structures (PythonEngine et al.) to retrieve info on the members that are available etc. I’ve done that, no problem. Of course in Python this is ridiculously easy anyway:
Python 2.5.1 (r251:54863, Feb 6 2009, 19:02:12) [GCC 4.0.1 (Apple Inc. build 5465)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> foo = "hi there" >>> foo.upper() 'HI THERE' >>> foo.__getattribute__("upper")() 'HI THERE' >>>
The only way that might work – and I haven’t followed up on this in any detail – is to write code similar to that usually created by the compiler, but manually. Looking at Reflector, this will make for an extremely horrible “API”, but I guess it’s possible. Although at the very least I’d have to use stuff out of the
System.Runtime.CompilerServices namespace, which seems a bit extreme… but who knows, maybe this is the way? Not intuitive, if it is! For some odd reason, I can’t currently find a good answer to this problem and I’m just now out of time to keep looking for it. I hope I’m missing something and somebody is going to come forward and tell me what it is.
It’s an odd fact that there are quite a few blog posts out there about how
dynamic in C# 4.0 is going to be so great instead of Reflection. Weird, because none of the posts I could find takes a very simple fact into account: I’m going to use Reflection scenarios mostly when I don’t know at design time what it is that I’m going to be invoking at runtime. Surely, that’s a very important point of it. Well. Seems like that is at least as hard with
dynamic, if perhaps more performant.
Sorry, this blog does not support comments. Why not?
I used various blog hosting services since this blog was established in 2005, but unfortunately they turned out to be unreliable in the long term and comment threads were lost in unavoidable transitions. At this time I don't want to enable third-party services for comments since it has become obvious in recent years that these providers invariably monetize information about their visitors and users.
Please use the links in the page footer to get in touch with me. I'm available for conversations on Keybase, Matrix, Mastodon or Twitter, as well as via email.