Create an AnonymousType from a dictionary

Today, i read an interesting article about creating strong typed anonymous types from weak typed data sources (e.g. Dictionary). The solution was to create something like an template anonymous type to get the type and use reflection to create a second instance of this type with the data from the dictionary. I think i have a better idea. What do you think about this solution:

[TestMethod]
        public void ToAnonymousTypeTest()
        {
            var dictionary = new Dictionary<string, object>
                                 {
                                     {"Name", "Tom"},
                                     {"Ignore", 2.5},
                                     {"IntegerValue", 5},
                                 };

            var anonymousTypeValue = dictionary.ToAnonymousType(
                (string Name, int IntegerValue) => new { Name, IntegerValue });

            Assert.AreEqual("Tom", anonymousTypeValue.Name);
            Assert.AreEqual(5, anonymousTypeValue.IntegerValue);
        }

The implementation of the dictionary extension methods ToAnonymousType:

    public static class DictionaryExtensions
    {
        public static TAnonymous ToAnonymousType<T1, TAnonymous>(this IDictionary<String, Object> dictionary, Func<T1, TAnonymous> getAnonymousType)
        {
            var parameters = getAnonymousType.Method.GetParameters();
            return getAnonymousType(
                (T1)dictionary[parameters[0].Name]);
        }

        public static TAnonymous ToAnonymousType<T1, T2, TAnonymous>(this IDictionary<String, Object> dictionary, Func<T1, T2, TAnonymous> getAnonymousType)
        {
            var parameters = getAnonymousType.Method.GetParameters();
            return getAnonymousType(
                (T1)dictionary[parameters[0].Name],
                (T2)dictionary[parameters[1].Name]);
        }

        public static TAnonymous ToAnonymousType<T1, T2, T3, TAnonymous>(this IDictionary<String, Object> dictionary, Func<T1, T2, T3, TAnonymous> getAnonymousType)
        {
            var parameters = getAnonymousType.Method.GetParameters();
            return getAnonymousType(
                (T1)dictionary[parameters[0].Name],
                (T2)dictionary[parameters[1].Name],
                (T3)dictionary[parameters[2].Name]);
        }

        public static TAnonymous ToAnonymousType<T1, T2, T3, T4, TAnonymous>(this IDictionary<String, Object> dictionary, Func<T1, T2, T3, T4, TAnonymous> getAnonymousType)
        {
            var parameters = getAnonymousType.Method.GetParameters();
            return getAnonymousType(
                (T1)dictionary[parameters[0].Name],
                (T2)dictionary[parameters[1].Name],
                (T3)dictionary[parameters[2].Name],
                (T4)dictionary[parameters[3].Name]);
        }
    }

Just add further extension methods when you need more than 4 properties on your anonymous type.

I have some ideas to improve the performance of the extension method, but i didn’t implement it yet, because i don’t need it. If you need better performance, just let me know.

4 Responses to Create an AnonymousType from a dictionary

  1. That is way cool, playing around with it now. It would be cool if you could do this:

    dictionary.ToAnonymousType(
    (string Name, int IntegerValue) => x new { x.Name, x.IntegerValue });

    So the intellisense would be scoped to only those variables you’re interested in. My guess is it’s possible somehow but maybe not, anyway, this is the first real solution I’ve found that will turn a dictionary into a anonymous type since anonymous types must be defined at compile time.

    Man, with that tweak above this could be even more awesome, gotta think about it, thanks for the post, very cool.

    • i’m not sure what u mean. the code u wrote is no valid c# code. what type should x be? u can already just define the properties u are interested in, no matter if more key value pairs are contained in the dictionary

  2. One more thing, you wrote this post in 2011, I wonder if ExpandoObject and the dynamic keyword could enhance this technique, you can do this now.

    ================================

    ExpandoObject o = new ExpandoObject();

    IDictionary dict = o;
    dict[“Name”] = “Mike”;
    dict[“IntegerValue”] = 9;

    dynamic d = o;

    string s = d.Name;

    ================================

    and it will compile just fine

    • sure u can use the DLR for this, too. but the DLR is not available on all platforms. For example i use portable libraries alot to share code between windows phone, silverlight, windows store and standard .net apps. The DLR is not available on some of these platforms. The second disadvantage is that u dont get intellisense for the properties on dynamics. The anomouse type solution gives u intellisense. And last but not least the use case that i had for this construct: i’ve implemented a expression based network services. Means that u just define a service interface and can call one or more methods including linq statements within one service call using an lambda expression (Expression). To when i was interested only in some values of a service methods result. I could reduce the transfered data by returning anonymous type results with the properties that i’m interested in instead of the whole service result object. To transfer (serialize) the anonymous values i used the dictionary. On the client side i restored the anonymous values from the dictionary, based on the lambda expression that has been used for the service call.

Leave a comment