Initialize an object of type T from Dictionary<string,object> Initialize an object of type T from Dictionary<string,object> json json

Initialize an object of type T from Dictionary<string,object>


DataContractJsonSerializer is too slow, but you're using reflection? If you have to deserialize lots of objects, I would recommend using compiled lambdas instead of reflection. A lambda can only set properties, not fields (at least in .Net 3.5), so you may have to adjust the classes you use it on, but it's worth it because it's like 1000 times faster.

Here's a function that creates a property setter given a type and a PropertyInfo for the property to set:

    static Action<object, TValue> MakeSetter<TValue>(Type tclass, PropertyInfo propInfo)    {        var t = lambda.Expression.Parameter(typeof(object), "t");        var v = lambda.Expression.Parameter(typeof(TValue), "v");        // return (t, v) => ((tclass)t).prop = (tproperty)v        return (Action<object, TValue>)            lambda.Expression.Lambda(                lambda.Expression.Call(                    lambda.Expression.Convert(t, tclass),                    propInfo.GetSetMethod(),                    lambda.Expression.Convert(v, propInfo.PropertyType)),                t,                v)            .Compile();    }

You would have a dictionary of setters for each class, and whenever you have to set a property of a class, you would look up the setter for that property in the dictionary and call it with the value to assign, like this: setters[propName](_this_, value);


I might suggest FormatterServices.PopulateObjectMembers, except a: this is still slow AFAIK, and b: I tried it (below) and it seems to want to throw an exception on the property (don't know why; didn't look too deep). Another option may be Expression, but you don't really want to do the Compile each time (better to do it once only and cache it, but that demands a known format).

public T create(object obj){  // simplified for illustration    var bindings = obj as IDictionary<string, object>;    Type type = typeof(T);    var func = Expression.Lambda<Func<T>>(Expression.MemberInit(        Expression.New(type),        from pair in bindings        let member = type.GetMember(pair.Key).Single()        select (MemberBinding)Expression.Bind(member, Expression.Constant(pair.Value))));    return func.Compile().Invoke();}

Finally, you might cache a set of pre-compiled Action<object> setters (keyed against the member name). In reality this is probably your best bet. Properties are easy (you use Delegate.CreateDelegate) - fields might need DynamicMethod - but if you can't predict the layout in advance it'll have the least overhead.

For the keyed / IL approach (you won't get faster):

public class dynamic_data_serializer<T>{    public T create(object obj)    {        T inst = Activator.CreateInstance<T>();        var bindings = obj as IDictionary<string, object>;        foreach (var pair in bindings)        {            setters[pair.Key](inst, pair.Value);        }        return inst;    }    private static readonly Dictionary<string, Action<T, object>> setters;    static dynamic_data_serializer()    {        setters = new Dictionary<string, Action<T, object>>(StringComparer.Ordinal);        foreach (PropertyInfo prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)) {            setters.Add(prop.Name, CreateForMember(prop));        }        foreach (FieldInfo field in typeof(T).GetFields(BindingFlags.Public | BindingFlags.Instance)) {            setters.Add(field.Name, CreateForMember(field));        }    }    static Action<T, object> CreateForMember(MemberInfo member)    {        bool isField;        Type type;        switch (member.MemberType) {            case MemberTypes.Property:                isField = false;                type = ((PropertyInfo)member).PropertyType;                break;            case MemberTypes.Field:                isField = true;                type = ((FieldInfo)member).FieldType;                break;            default:                throw new NotSupportedException();        }        DynamicMethod method = new DynamicMethod("__set_" + member.Name, null, new Type[] { typeof(T), typeof(object) });        ILGenerator il = method.GetILGenerator();        il.Emit(OpCodes.Ldarg_0);        il.Emit(OpCodes.Ldarg_1);        if(type != typeof(object)) {            il.Emit(type.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type);        }        if (isField) {il.Emit(OpCodes.Stfld, (FieldInfo)member);}        else { il.EmitCall(OpCodes.Callvirt, ((PropertyInfo)member).GetSetMethod(), null);  }        il.Emit(OpCodes.Ret);        return (Action<T, object>)method.CreateDelegate(typeof(Action<T, object>));    }}


DataContractJsonSerializer

Why would you make a custom serializer and not use the DataContractJsonSerializer?

EDIT

If DataContractJsonSerializer doesn't fit you, you can try JSON.Net. Implementing a serializer efficiently is not an easy task, there's a lot of pitfalls and special cases that you may not want to get into. By the way, your code sample makes heavy use of reflection which is slow, I doubt that it will perform better than DataContractJsonSerializer or JSON.Net.