62,046
社区成员
发帖
与我相关
我的任务
分享
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Time { get; set; }
public UserType Type { get; set; }
}
public enum UserType
{
Unkown = 0,
Admin = 1,
LoginUser = 2,
Guest = 3
}
class Program
{
static void Main(string[] args)
{
//模拟Request.Form或者Request.QueryString对象
NameValueCollection nvc = new NameValueCollection();
nvc.Add("Id", "11");
nvc.Add("Name", "coffee11");
//t0对象
nvc.Add("t0.Id", "1");
nvc.Add("t0.Name", "coffee1");
nvc.Add("t0.Time", "2015-03-24");
//t1对象
nvc.Add("t1.Id", "2");
nvc.Add("t1.Name", "coffee2");
nvc.Add("t1.Type", "admin");
var user = nvc.ToModel<User>();
var user0 = nvc.ToModel<User>("t0");
var user1 = nvc.ToModel<User>("t1");
Console.ReadLine();
}
}
private static Func<NameValueCollection, string, object> CreateFunc(Type type)
{
DynamicMethod method = new DynamicMethod("", typeof(object), new Type[] { typeof(NameValueCollection), typeof(string) }, true);
ILGenerator il = method.GetILGenerator();
//new一个需要返回的对象
il.DeclareLocal(type);
il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));
il.Emit(OpCodes.Stloc_0); //var t = new T()
var lbl = il.DefineLabel();
//string temp = null;
var loc_1 = il.DeclareLocal(typeof(string));
//if (!string.IsNullOrEmpty(prefix))
// temp += "."
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Call, typeof(string).GetMethod("IsNullOrEmpty"));
il.Emit(OpCodes.Brtrue, lbl);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ldstr, ".");
il.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }));
il.Emit(OpCodes.Stloc, loc_1);
il.MarkLabel(lbl);
var props = type.GetProperties(BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.Public);
foreach (var item in props)
{
//var temp_key = temp + item.Name
var loc_temp_key = il.DeclareLocal(typeof(string));
il.Emit(OpCodes.Ldloc, loc_1);
il.Emit(OpCodes.Ldstr, item.Name);
il.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }));
il.Emit(OpCodes.Stloc, loc_temp_key);
//var temp_value = collection[temp_key];
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc, loc_temp_key);
var loc_temp_value = il.DeclareLocal(typeof(string));
il.Emit(OpCodes.Call, typeof(System.Collections.Specialized.NameValueCollection).GetMethod("get_Item", new Type[] { typeof(string) }));
il.Emit(OpCodes.Stloc, loc_temp_value);
//if (string.IsNullOrEmpty(temp_value))
// continute;
var for_lbl = il.DefineLabel();
il.Emit(OpCodes.Ldloc, loc_temp_value);
il.Emit(OpCodes.Call, typeof(string).GetMethod("IsNullOrEmpty"));
il.Emit(OpCodes.Brtrue, for_lbl);
Type propType = item.PropertyType;
var loc_object_value = il.DeclareLocal(typeof(object));
//object object_value = ChangeType(temp_value, propType);
il.Emit(OpCodes.Ldloc, loc_temp_value);
il.Emit(OpCodes.Ldtoken, propType);
il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) }));
il.Emit(OpCodes.Call, typeof(ModelHelper).GetMethod("ChangeType"));
il.Emit(OpCodes.Stloc, loc_object_value);
//if (object_value == null)
// continute;
il.Emit(OpCodes.Ldloc, loc_object_value);
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Ceq);
il.Emit(OpCodes.Brtrue, for_lbl);
//对进行过类型转换的结果进行拆箱
var loc_type_value = il.DeclareLocal(propType);
il.Emit(OpCodes.Ldloc, loc_object_value);
il.Emit(OpCodes.Unbox_Any, propType);
il.Emit(OpCodes.Stloc, loc_type_value);
//t.XXX = type_value;
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldloc, loc_type_value);
il.Emit(OpCodes.Callvirt, item.GetSetMethod());
il.MarkLabel(for_lbl);
}
//return t;
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);
return method.CreateDelegate(typeof(Func<NameValueCollection, string, object>)) as Func<NameValueCollection, string, object>;
}