Dynamic capabilities were added to C# 4.0. These capabilities provide the ability to intercept method and property invocations. In certain situations, this is extremely useful, as seen in SignalR.
I’m currently working on an XMPP library which parses a received XMPP Stanza into a class named BvElement. Abstracting from BvElement are classes such as IQ, Message, and Presence.
In a non-dynamic world I have to create properties to represent XML child nodes, or a method which accepts a name and performs the appropriate lookup. This leads to a proliferation of properties, and in most cases this is completely unnecessary – if the node is not present or empty, the consumer will handle that, I just need to return a BvElement representing the node. Where default behavior is expected, for example get is the default type of an IQ stanza, I need a property. But for most purposes, this is not necessary, especially since XMPP is extensible by design.
So instead of writing zillions of properties, using dynamic I am able to achieve code like this, which sets the namespace attribute from a Query element of an IQ:
If Query doesn’t exist, an empty element named Query is created and returned. If the Namespace attribute doesn’t exist, an empty attribute named Namespace is created. This greatly simplifies client-side code, there is no need for null testing. It’s pretty much the Null Object Pattern at work.
So how does it work? Firstly, I need to inherit from DynamicObject.
Try Get Member
Then I implement the TryGetMember method, which is invoked if a method or property does not exist. In this method I look for the requested element, if it is present I return it, otherwise I add the required element before returning it.
Try Set Member
Lastly, I implement the TrySetMember method. Here I am setting the value of an element, creating the element if it doesn’t exist.
The last piece of the puzzle is the dynamic keyword. You must use this type in order to access the dynamic features:
Now you can use it as mentioned above, i.e. iq.Query[Xl.Namespace]…
Dynamic is an excellent addition to C#, and surprisingly it performs much faster than reflection. It’s another paradigm for solving problems.
I hope this post helps, you can find the source code for the above class online here.