private static void Parse(ILGenerator il, Type type) { if (type.GetTypeInfo().IsValueType) { //可空类型 if (EmitUtil.IsNullable(type)) { var realType = EmitUtil.GetNullableArg0(type); il.Emit(OpCodes.Call, realType.GetTypeInfo().GetMethod("Parse", new[] { typeof(string) })); // ReSharper disable once AssignNullToNotNullAttribute il.Emit(OpCodes.Newobj, type.GetTypeInfo().GetConstructor(new[] { realType })); } else { il.Emit(OpCodes.Call, type.GetTypeInfo().GetMethod("Parse", new[] { typeof(string) })); } } }
private static LocalBuilder GetRealLocal(ILGenerator il, Type type, Dictionary <Type, LocalBuilder> realValueDict) { LocalBuilder localBuilder; Type realType = type; //可空类型或者Datetime类型,都需要将参数存储起来 if (EmitUtil.IsNullable(type)) { realType = EmitUtil.GetNullableArg0(type); } if (realValueDict.ContainsKey(realType)) { localBuilder = realValueDict[realType]; } else { localBuilder = il.DeclareLocal(realType); realValueDict.Add(realType, localBuilder); } return(localBuilder); }
private static void PropertyToString(ILGenerator il, Type type, Dictionary <Type, LocalBuilder> valueDict) { //值类型和可空类型 if (type.GetTypeInfo().IsValueType) { //不可空类型,直接创建新的,可空类型就先从字典中取,取不到再新建 var localBuilder = GetLocal(il, type, valueDict); il.Emit(OpCodes.Stloc_S, localBuilder); il.Emit(OpCodes.Ldloca_S, localBuilder); if (type == typeof(DateTime) || type == typeof(DateTime?)) { //可空datetime类型 if (type == typeof(DateTime?)) { il.Emit(OpCodes.Call, type.GetTypeInfo().GetMethod("get_Value", new Type[] { })); var realLocal = GetRealLocal(il, type, valueDict); il.Emit(OpCodes.Stloc_S, realLocal); il.Emit(OpCodes.Ldloca_S, realLocal); } il.Emit(OpCodes.Call, CultureInfo); il.Emit(OpCodes.Call, DatetimeToString); } else { if (EmitUtil.IsNullable(type)) { il.Emit(OpCodes.Call, type.GetTypeInfo().GetMethod("get_Value", new Type[] { })); var realLocal = GetRealLocal(il, type, valueDict); il.Emit(OpCodes.Stloc_S, realLocal); il.Emit(OpCodes.Ldloca_S, realLocal); } il.Emit(OpCodes.Call, EmitUtil.GetNullableArg0(type).GetTypeInfo().GetMethod("ToString", new Type[] { })); } } }
/// <summary>获取将对象转换成字典类型的委托 /// </summary> public static Func <T, Dictionary <string, string> > GetDictionaryFunc <T>() { if (typeof(ICollection).GetTypeInfo().IsAssignableFrom(typeof(T))) { throw new NotSupportedException("Not support type: ICollection"); } var type = typeof(Dictionary <string, string>); var properties = PropertyInfoUtil.GetProperties(typeof(T)); DynamicMethod dynamicMethod = new DynamicMethod("ObjectToDictionary", type, new Type[] { typeof(T) }, typeof(object), true) { InitLocals = true }; ILGenerator il = dynamicMethod.GetILGenerator(); //结束标签 Label endLabel = il.DefineLabel(); //定义变量 var user=new User();他为第0个变量 LocalBuilder obj = il.DeclareLocal(type); //定义了可空类型的变量集合 Dictionary <Type, LocalBuilder> valueDict = new Dictionary <Type, LocalBuilder>(); // ReSharper disable once AssignNullToNotNullAttribute il.Emit(OpCodes.Newobj, type.GetTypeInfo().GetConstructor(Type.EmptyTypes)); il.Emit(OpCodes.Stloc, obj); int index = 0; foreach (var property in properties) { Label endIfLabel = il.DefineLabel(); //string,可空类型需要null判断 if (property.PropertyType == typeof(string)) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, property.GetGetMethod()); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Cgt_Un); var tmp = il.DeclareLocal(typeof(bool)); il.Emit(OpCodes.Stloc, tmp); il.Emit(OpCodes.Ldloc, tmp); il.Emit(OpCodes.Brfalse_S, endIfLabel); } //可空类型 if (EmitUtil.IsNullable(property.PropertyType)) { var hasValue = il.DeclareLocal(typeof(bool)); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, property.GetGetMethod()); var local = GetLocal(il, property.PropertyType, valueDict); il.Emit(OpCodes.Stloc_S, local); il.Emit(OpCodes.Ldloca_S, local); il.Emit(OpCodes.Call, property.PropertyType.GetTypeInfo().GetMethod("get_HasValue", new Type[] { })); if (index == 0) { il.Emit(OpCodes.Stloc, hasValue); il.Emit(OpCodes.Ldloc, hasValue); } else { il.Emit(OpCodes.Stloc_S, hasValue); il.Emit(OpCodes.Ldloc_S, hasValue); } index++; il.Emit(OpCodes.Brfalse_S, endIfLabel); } il.Emit(OpCodes.Ldloc, obj); il.Emit(OpCodes.Ldstr, property.Name); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, property.GetGetMethod()); //取对象属性值 PropertyToString(il, property.PropertyType, valueDict); il.Emit(OpCodes.Callvirt, DictionaryAddItem); il.MarkLabel(endIfLabel); } var result = il.DeclareLocal(type); il.Emit(OpCodes.Ldloc, obj); il.Emit(OpCodes.Stloc_S, result); il.Emit(OpCodes.Br_S, endLabel); il.MarkLabel(endLabel); il.Emit(OpCodes.Ldloc_S, result); il.Emit(OpCodes.Ret); var func = dynamicMethod.CreateDelegate(typeof(Func <T, Dictionary <string, string> >)) as Func <T, Dictionary <string, string> >; if (func == null) { throw new VerificationException(); } return(func); }