Copied directly from ayende.com
Given a Dictionary<string, string>, convert that dictionary into a type in as performant a manner as possible. The conversion will happen many time, and first time costs are acceptable.
public static Func<Dictionary<string, string>, T> Generate<T>()
where T : new()
{
var dic = Expression.Parameter(typeof (Dictionary<string, string>), "dic");
var tmpVal = Expression.Parameter(typeof (string), "tmp");
var args = new List<MemberAssignment>();
foreach (var propertyInfo in typeof(T).GetProperties())
{
var tryGet = Expression.Call(dic, "TryGetValue", new Type[0],
Expression.Constant(propertyInfo.Name),
tmpVal);
Expression value = tmpVal;
if (propertyInfo.PropertyType != typeof (string))
{
var convertCall = Expression.Call(typeof(Convert).GetMethod("ChangeType",
new Type[] { typeof(object), typeof(Type) }), tmpVal,
Expression.Constant(propertyInfo.PropertyType));
value = Expression.Convert(convertCall, propertyInfo.PropertyType);
}
var conditional = Expression.Condition(tryGet, value,
Expression.Default(propertyInfo.PropertyType));
args.Add(Expression.Bind(propertyInfo, conditional));
}
var newExpression = Expression.New(typeof(T).GetConstructor(new Type[0]));
var expression = Expression.Lambda<Func<Dictionary<string, string>, T>>(
Expression.Block(new[] { tmpVal },Expression.MemberInit(newExpression,args)),
dic);
return expression.Compile();
}
this code does is dynamically generate the following method
(Dictionary<string,string> dic) => {
string tmp;
return new User
{
Name = dic.TryGetValue("Name", out tmp) ? tmp : default(string),
Age = dic.TryGetValue("Age", out tmp) ? (int)Convert.ChangeType(tmp, typeof(int)) : default(int)
};
}