来博客园已经很多年了,一直很懒,没写过博客,都是偷偷的关注园子里大牛门
看他们的动向,跟着他们的脚步学习知识。
这次也算是一点反馈吧,记得前一段时间看过一个园友写过一个DataTable转换成List<T>的文章
受到了不少启发,于是有了下面的一小段代码,写他的目的也不算是重复的造轮子,只是为了温习一下Emit
不然久了真的忘记了。
废话少说了,直接上代码,有注释的哦,我就不解释了
想学习Emit的同学可以对照OpCodes的指令来看,肯定会有收获的
static Func<DataRow, T> CreateFunc<T>() where T : new() { Type classType = typeof(T); DynamicMethod method = new DynamicMethod("", typeof(T), new Type[] { typeof(DataRow) }, true); ILGenerator il = method.GetILGenerator(); //new一个需要返回的对象 il.DeclareLocal(classType); il.Emit(OpCodes.Newobj, classType.GetConstructor(Type.EmptyTypes)); il.Emit(OpCodes.Stloc_0); //var t = new T() //取出dr中所有的列名集合 il.DeclareLocal(typeof(DataColumnCollection)); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, typeof(DataRow).GetMethod("get_Table")); il.Emit(OpCodes.Callvirt, typeof(DataTable).GetMethod("get_Columns")); il.Emit(OpCodes.Stloc_1); //var columns = dr.Table.Columns var props = classType.GetProperties(BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty | BindingFlags.Public); foreach (var property in props) { var label = il.DefineLabel(); il.Emit(OpCodes.Ldloc_1); il.Emit(OpCodes.Ldstr, property.Name); il.Emit(OpCodes.Callvirt, typeof(DataColumnCollection).GetMethod("Contains")); //判断dr中是否有此列名 il.Emit(OpCodes.Brfalse, label); // if (!columns.Contains("xx")) il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldstr, property.Name); //取出dr中对应的列的值 il.Emit(OpCodes.Callvirt, typeof(DataRow).GetMethod("get_Item", new Type[] { typeof(string) })); //var temp = dr["xx"] //对取出的值拆箱 il.Emit(OpCodes.Unbox_Any, property.PropertyType); var temp = il.DeclareLocal(property.PropertyType); il.Emit(OpCodes.Stloc, temp); //t.xx = temp il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldloc, temp); il.Emit(OpCodes.Callvirt, property.GetSetMethod()); il.MarkLabel(label); } il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ret); return method.CreateDelegate(typeof(Func<DataRow, T>)) as Func<DataRow, T>; }
下面给出一个测试的代码片段
public class User { public int ID { get; set; } public string Name { get; set; } }
var func = CreateFunc<User>(); DataTable dt = new DataTable(); dt.Columns.Add("ID", typeof(int)); //dt.Columns.Add("name", typeof(string)); var dr = dt.NewRow(); dr[0] = 13; //dr[1] = "coffee"; dt.Rows.Add(dr); var user = func(dr);
第一次发文,斗胆放上首页,请各位大牛不吝赐教~~~