C# 4.0 introduces the new 'dynamic' keyword to the language, adding dynamic support to the .NET Framework though the DLR (Dynamic Language Runtime).
My first understanding of the use of such a dynamic support was the following:
- Great to use for inter-connections with dynamic langages, avoiding to have to write too complex code to bridge the gap between the 2 languages.
- Great to use for instance for Microsoft Office automation. MS Office automation is done though COM objects. Previous use of MS Office PIA was cumbersome. The new dynamic keyword makes much less verbose.
- Enhance support for reflection.
With the dynamic keyword, type checking is no more done at compile time but will be done at runtime. Thus making code writing more flexible (especially when using uncertain type, only known at runtime). However it makes writing code less safe (no compile checking) and less productive (no intellisense). Therefore one should not use the dynamic keyword in C#, except in previous cases. And use instead Object orientation design principles and patterns to achieve safe, strongly-typed coding. Moreover, the addition of generics to the .NET Framework 2.0 was a huge step forward to enable better object orientation and strong typing.
So IMHO the dynamic keyword and DLR is a great thing to have but will also be an added opportunity to write bad code and break core design principles. So one should be aware of it and use it sparingly, when making real sense!
Moreover be aware that the use of the dynamic keyword has a performance hit: because runtime discovery and type checking has to be done at runtime.
I came accross a post from Peter Ritchie highlighting another great use of the dynamic keyword. I said previously that when developing in C#, you should use as much as possible proper object orientation principle and patterns to write proper good code (because C# is a OO language). However there are cases where it is not easy to write full pure object oriented code. And Peter describes one of these cases and how the dynamic keyword can help:
The case is the following (for more details please refer to Peter Ritchie's post):
When you use method overloading to define methods that take different flavors of a given type hierarchy (Circle and Square both derive from Shape):
public static void Draw(Circle circle) { //... } public static void Draw(Square square) { //... }
When you want to call the Draw method, you have to call it with an object that is known at compile time to be either a Circle or a Square (or inheriting from Circle or Square). You cannot call it generically with a object of type Shape. This is because the compiler must know which method overload to link to.
Please note that this example is probably not the best as a solution could be to define the Draw method on the Shape class and override it on both Circle and Square. However there are cases where this scenario really makes sense, so just take this as a sole demonstration purpose, and get the idea of what the dynamic keyword could bring.
Back to our example, the following method will not compile:
public void ProcessShape(Shape shape) { //... Draw(shape); //... }
You instead have to write something like
public void ProcessShape(Shape shape) { //... if (!ReferenceEquals(null, shape as Square)) { Draw(shape as Square); } if (!ReferenceEquals(null, shape as Circle)) { Draw(shape as Circle); } //... }
Thus wasting the interest of object orientation, adding a maintenance point for when new Shape types are added etc...
Solution with using the dynamic keyword is:
public void ProcessShape(Shape shape) { //... dynamic dynShape = shape; Draw(dynShape); //... }
The type checking done previously in code is now done by the DLR and the code is more robust: we have elimintated the maintenance point.
And here is the full code that demonstrate the use of the dynamic keyword (just create a Console app to include this code):
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { public class Shape { } public class Circle : Shape { } public class Square: Shape { } class Program { static void Main(string[] args) { Shape myShape = null; myShape = new Square(); ProcessShape(myShape); myShape = new Circle(); ProcessShape(myShape); Console.ReadLine(); } static void ProcessShape(Shape shape) { //Draw(shape); dynamic dynShape = shape; Draw(dynShape); } static void Draw(Square square) { Console.WriteLine("I am a Square"); } static void Draw(Circle circle) { Console.WriteLine("I am a Circle"); } }
}
This is a great use of the dynamic keyword. However: this is also a good example to show that the dynamic keyword could be used improperly instead of a right object oriented design: We said before that in this specific case, it could probably better to add a Draw method on the Shape class and override it on derived class : this is a basic OO design principle: classes embed data and behavior. Thing is there is no definite rule: depending on your overall design and architecture (and especially the level of coupling you want to have), it could be good design to have the Draw method excluded from the Shape class. So nothing replaces experience, however the enhancement of the programming languages will add more and more confusion for beginners! And this makes the software design and development really challenging and exciting!
Recent Comments