Thursday, June 26, 2014

Dynamic and ExpandoObject

Intro

Ahh, dynamic types. For those who love anarchy, disorder, and a total lack of type-safe compile-time code wrangling, dynamic types are quite a boon. There are many languages out there that facilitate such things, JavaScript being one of the largest among them. And while I consider myself to be firmly in the camp of "type-safety is good!", I do recognize that there are a few valid uses for dynamic types in my cozy little type-safe bubble that is c#.

As you can guess from the title of this post and the preceding paragraph, this post is going to be about dynamic and ExpandoObject. I won't get into the nitty gritty details of either, as I prefer the 30,000 ft view here. We'll cover how to use them and what you might do with them, but without opening up the hood too much. If you wish to dig further you can read the links towards the bottom of the blog.

When to Use

Have you ever had to interact with type-unsafe services and languages? For example, have you ever integrated a c# app with Facebook, Twitter, or any other such 3rd party service that returns a JSON object? Or, have you perhaps written a JSON Web API yourself? Being the client of such a service will almost invariably involve either you creating proxy classes that represent the data returned so that you can parse the JSON into your friendly object structure, or hey, we will soon see how to do such things with dynamic objects!

I'm sure there are other uses too, but this is the main one I've run into and I've run into it multiple times so I assume it must be fairly common. After all, a sample size of 1 among the millions of programmers in the wold has to be statistically significant.

How to Use

Our first sample will be a simple one; we're just going to create a dynamic object and add some properties and a method to it, without declaring the object type ahead of time. Let's jump right in:

        
        public string DoStuff()
        {
            dynamic myDynamicVariable = new ExpandoObject();
            myDynamicVariable.Name = "Fred";
            myDynamicVariable.Age = 34;
            myDynamicVariable.ToString = new Func<string>(() => { return myDynamicVariable.Name + "::" + myDynamicVariable.Age; });
            return myDynamicVariable.ToString();
        }



In the above code, we first declare a variable named myDynamicVariable of type dynamic, and initialize it to a new instance of ExpandoObject. The combination of dynamic and ExpandoObject is the magic sauce that makes the code below it function properly. Notice how we never declared or used some special class that has a Name or Age property, or a ToString method? Yet, through the awesomeness of dynamics the value we want is returned by the method DoStuff.The return statement returns the result of a call to the ToString method of myDynamicVariable, and in this case returns the string "Fred::34". When I first saw code similar to this, I was amazed it even compiled much less ran! All we had to do was declare our type and start putting new properties and values into our class, and we can even declare methods inline. Groovy! What would happen if you tried the same thing with an object of type "Object"? If you guessed compiler error, treat yourself to a hearty pat on the back, because you're right! Dynamic types give you the power to modify object properties with a clean syntax, without declaring the type ahead of time.

For our second sample we'll be using the JSON.Net NuGet package to import a JSON string into a dynamic object. In my opinion, this is the best type of usage for dynamic objects. Let's look at the sample code before I get ahead of myself here:

        public KeyValuePair<string, int> DoJsonStuff()
        {
            string json = "{ 'SomeStringProp': 'Hey, a string!', 'SomeIntProp': 42  }";
            dynamic deserializedObject = JsonConvert.DeserializeObject<dynamic>(json);
            return new KeyValuePair<string, int>((string)deserializedObject.SomeStringProp, (int)deserializedObject.SomeIntProp);
        }



The first line sets the JSON value we are going to parse. The 2nd line uses JSON.Net to deserialize the JSON string into a dynamic object using the call JSONConvert.DeserializeObject. The 3rd line returns our KeyValuePair, which as you have guessed contains the values "Hey, a string!" and 42.

Now imagine you have just called the Twitter API to retrieve a user's feed. Twitter responds with a JSON list of object that is fairly large in many cases, and contains lots and lots of properties and sub-object. Do you want to go map what comes back to statically typed classes? Well I do actually, but hey it's not everyone's cup of queso and as you can see, dynamics aren't hard to work with in .Net.


What's Next?

  • Read up more on the dynamic keyword
  • Read up more on ExpandoObject
  •  Learn how to create anonymous methods using the Func type (and others!)
  • Go hog-wild and read up on JSON.Net

No comments:

Post a Comment