While I was playing around with deserializing objects written in JSON format, I noticed that I had to write a lot of classes that were used just to deserialize the JSON response. I noticed that I did not necessarily needed those classes, and that I often would just transfer data from those classes back into my own objects. Basically, I ended up with a lot of classes which were used just to get the JSON response into objects.

I started thinking about how I could leverage C# language features to accomplish the same goals. I this article I am going to show you how you can use the C# 3.0 anonymous types feature to deserialize JSON data back into objects. For parsing JSON and assigning values to my object I will use this JSON implementation.

C# 2.0

The JSON text that I am trying to parse is this:

string JSONText = "{Text:\"Hello World!!\", Status:\"Ok\"}";

In order to do this, I would have to create a class (with any name) that will have the two properties Text and Status:

class HelloWorldResponse
{
    public string Text { get; set; }
    public string Status { get; set; }
}

And now, in order to deserialize the data, I use the JSON serializer like so:

var x = js.Deserialize(new StringReader(JSONText), typeof(HelloWorldResponse)) as HelloWorldResponse;

C# 3.0

In C# 3.0 we introduced the notion of anonymous types - types that have no name that you can speak - that can have any shape you want. The main reason why they were introduced is to support LINQ, but they can be used in other way as well.

So, in C# 3.0 instead of writing my own classes, I decided to let the compiler do the work for me. What I will do is to create the anonymous types in the function that need that response. I will pass the anonymous type to the JSON deserializer and get back an object that contains an anonymous type populated with the data from the JSON string. To get from object to the strongly typed anonymous type, I will use a generic method that casts the object to the type of the anonymous type .

Here is the method that converts object to the anonymous type:

public static class TypeExtension
{
    public static T ToType<T>(this object o, T typeToCastTo)
    {
        return (T)o;
    }
}

This is a generic extension method that takes in two arguments: the object I am trying to convert and the type I am converting to. The compiler will do type inference on the argument going in, so if I pass in a variable of an anonymous type, it will figure out the unspeakable name for the anonymous type. Then, it just returns the result of the converson from the object to that type.

Then, I can just write the code like this:

var helloResponse = new { Text = string.Empty, Status = string.Empty };
var y = js.Deserialize(new StringReader(JSONText), helloResponse.GetType()).ToType(helloResponse);

And then, y will hold a reference to an anonymous type and I can use it to read the properties from the type.

The advantage that I am getting is not in the number of classes that I have to write - the compiler will generate the same number of classes* as I would have.  The disadvantage to this solution is the fact that now I have type definitions inside methods, which can make it harder to debug/change. Also, if your internal classes map directly to the response you get as JSON, then you are probably better off using "real classes".

C# 4.0

In C# 4.0, with the introduction of dynamic, we can further simplify this code. In C# 4.0, I don't need the method that will convert from object to the anonymous type. I can just stick the object returned from the JSON deserializer into a dynamic and use dynamic dispatch to get to the members that I care about:

var helloResponse = new { Text = string.Empty, Status = string.Empty }; 
dynamic y = js.Deserialize(new StringReader(JSONText), helloResponse.GetType());

The disadvantage of this solution is that you will not have IntelliSense one you go dynamic, so any spelling mistake will not be caught by the compiler.

So here you go - 3 ways of doing the same thing, each with their pros and cons. I really like to C# 3.0/ C# 4.0 versions where you create the type "on the fly" and then you go ahead and use result. I still don't like the fact that I need to explicitly state what are the members on the type. I would just like to get "a" type back and then magically get just the members I care about. Well - we'll see :).

*the compiler will try to reuse similar anonymous types, so you might actually get fewer types