It’s undeniable that the dynamic feature in C# is a powerful tool for any programmer. However, some might argue that it’s more of a novelty than a practical solution for real-world programming. To challenge this notion, let’s explore some compelling use cases for dynamic.
JSON Parsing Without Class Definitions: While
JavaScriptSerializerandDataContractJsonSerializerare standard tools for JSON deserialization, they require pre-defined classes. What if the structure is unknown or defining classes feels cumbersome? We can utilizeExpandoObjectto parse JSON into an object with fields dynamically representing arrays, strings, numbers, or even nestedExpandoObjects. This approach offers flexibility when dealing with unpredictable JSON structures. Here’s a simple implementation (inspired by [this source](http://coderjournal.com/2010/07/turning-json-into-a-expandoobject/)):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36public static ExpandoObject Expando(this IDictionary dictionary) { var expando = new ExpandoObject(); var expandoDic = (IDictionary)expando; foreach (var item in dictionary) { bool alreadyProcessed = false; if (item.Value is IDictionary) { expandoDic.Add(item.Key, Expando((IDictionary)item.Value)); alreadyProcessed = true; } else if (item.Value is ICollection) { var itemList = new List(); foreach (var item2 in (ICollection)item.Value) if (item2 is IDictionary) itemList.Add(Expando((IDictionary)item2)); else itemList.Add(Expando(new Dictionary { { "Unknown", item2 } })); if (itemList.Count > 0) { expandoDic.Add(item.Key, itemList); alreadyProcessed = true; } } if (!alreadyProcessed) expandoDic.Add(item); } return expando; }The Power of ElasticObject: The
ElasticObject([found in AmazedSaint’s blog](http://www.amazedsaint.com/2010/02/introducing-elasticobject-for-net-40.html)) takes dynamic object creation a step further. Its standout feature? The ability to create nested properties on the fly. If you access a non-existent property of another non-existent property, `ElasticObject` automatically creates both. Let's compare this to JavaScript:JavaScript: Requires explicit property creation. Accessing non-existent properties throws an error.
1 2 3 4 5 6 7var ob = {}; ob.name = "xose"; ob.address = {}; ob.address.street = "Leipziger strasse"; // Error: 'favorites' is undefined ob.favorites.book = "1984";C# with ElasticObject: Dynamically creates missing properties, streamlining object construction.
1 2 3 4 5 6 7 8dynamic ob = new ElasticObject(); ob.name = "xose"; // No need to explicitly create 'address' ob.address.street = "Leipziger strasse"; // Works seamlessly ob.favorites.book = "1984";
Simplified Reflection with
ExposedObject: Reflection, while powerful, can be verbose.ExposedObjectleveragesdynamicto offer a cleaner syntax for accessing private members.This blog post highlights its elegance. By wrapping objects with
ExposedObject, we can interact with private properties and methods using a simplified syntax. Note: usingdynamicalone won’t grant access to private members; theExposedObjectwrapper is crucial.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22dynamic p1 = new Person("Iyan", 36); Console.WriteLine("using Reflection:"); PropertyInfo pr = p1.GetType().GetProperty("Name"); Console.WriteLine(pr.GetValue(p1, null)); Console.WriteLine("using dynamic:"); Console.WriteLine(p1.Name); try { Console.WriteLine(p1.age); } catch(Exception ex) { //with the normal dynamic behaviour we get an exception when trying to get access to private items Console.WriteLine("Exception: " + ex.ToString()); } Console.WriteLine("using ExposedObject:"); dynamic expP1 = ExposedObject.From(p1); Console.WriteLine(expP1.Name); Console.WriteLine(expP1.age);
These examples illustrate how dynamic enhances code readability and efficiency. Even without custom DynamicObject implementations, the dynamic keyword streamlines tasks like deserialization or data mapping, making code more expressive. Additionally, the DLR’s caching mechanism can lead to performance improvements, as Eric Lippert pointed out (source):
“With Reflection you do not get any cached behaviour… With the DLR, the first operation is very slow indeed as it does a huge amount of analysis, but the analysis is cached and reused. That consumes memory, in exchange for increased speed in subsequent calls in some scenarios.”
The key takeaway? C#’s dynamic isn’t just a fancy feature. When used thoughtfully, it can simplify complex tasks, improve code readability, and even boost performance. For further exploration on advanced C# topics, this blog offers insightful articles like the one on
```