/// <summary> /// DefineDerivedMethodSignature 定义动态类中方法的签名,支持泛型方法。 /// </summary> public static MethodBuilder DefineDerivedMethodSignature(TypeBuilder typeBuilder, MethodInfo baseMethod) { Type[] argTypes = EmitHelper.GetParametersType(baseMethod); MethodBuilder methodBuilder = typeBuilder.DefineMethod(baseMethod.Name, baseMethod.Attributes & ~MethodAttributes.Abstract, baseMethod.ReturnType, argTypes); #region GenericMethod if (baseMethod.IsGenericMethod) { Type[] genericParaTypes = baseMethod.GetGenericArguments(); string[] genericParaNames = EmitHelper.GetGenericParameterNames(baseMethod); GenericTypeParameterBuilder[] genericTypeParameterBuilders = methodBuilder.DefineGenericParameters(genericParaNames); for (int i = 0; i < genericTypeParameterBuilders.Length; i++) { genericTypeParameterBuilders[i].SetInterfaceConstraints(genericParaTypes[i].GetGenericParameterConstraints()); } } #endregion return(methodBuilder); }
/// <summary> /// Stind 间接存储(即存储[type类型]的对象地址)。将间接存储。不支持decimal类型 /// </summary> public static void Stind(ILGenerator ilGenerator, Type type) { if (!type.IsValueType) { ilGenerator.Emit(OpCodes.Stind_Ref); return; } if (type.IsEnum) { Type underType = Enum.GetUnderlyingType(type); EmitHelper.Stind(ilGenerator, underType); return; } if (type == typeof(Int64)) { ilGenerator.Emit(OpCodes.Stind_I8); return; } if (type == typeof(Int32)) { ilGenerator.Emit(OpCodes.Stind_I4); return; } if (type == typeof(Int16)) { ilGenerator.Emit(OpCodes.Stind_I2); return; } if (type == typeof(Byte)) { ilGenerator.Emit(OpCodes.Stind_I1); return; } if (type == typeof(SByte)) { ilGenerator.Emit(OpCodes.Stind_I1); return; } if (type == typeof(Boolean)) { ilGenerator.Emit(OpCodes.Stind_I1); return; } if (type == typeof(UInt64)) { ilGenerator.Emit(OpCodes.Stind_I8); return; } if (type == typeof(UInt32)) { ilGenerator.Emit(OpCodes.Stind_I4); return; } if (type == typeof(UInt16)) { ilGenerator.Emit(OpCodes.Stind_I2); return; } if (type == typeof(Single)) { ilGenerator.Emit(OpCodes.Stind_R4); return; } if (type == typeof(Double)) { ilGenerator.Emit(OpCodes.Stind_R8); return; } if (type == typeof(IntPtr)) { ilGenerator.Emit(OpCodes.Stind_I4); return; } if (type == typeof(UIntPtr)) { ilGenerator.Emit(OpCodes.Stind_I4); return; } throw new Exception(string.Format("The target type:{0} is not supported by EmitHelper.Stind_ForValueType()", type)); }
private void EmitSetPropertyValueMethod(TypeBuilder typeBuilder, MethodInfo baseMethod, Type entityType) { var methodBuilder = typeBuilder.DefineMethod("SetPropertyValue", baseMethod.Attributes & ~MethodAttributes.Abstract, baseMethod.CallingConvention, baseMethod.ReturnType, EmitHelper.GetParametersType(baseMethod)); var compareStringMethod = typeof(string).GetMethod("op_Equality", new[] { typeof(string), typeof(string) }); var changeTypeMethod = typeof(TypeUtil).GetMethod("ChangeType", new[] { typeof(Type), typeof(object) }); var ilGenerator = methodBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Nop); var tempPros = entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags .GetProperty); // ESBasic.Helpers.TypeUtil.ConvertListToArray<PropertyInfo>(columnList); IList <PropertyInfo> proList = new List <PropertyInfo>(); foreach (var propertyInfo in tempPros) { if (propertyInfo.CanWrite && propertyInfo.CanRead) { proList.Add(propertyInfo); } } var pros = proList.ToArray(); var retLabel = ilGenerator.DefineLabel(); var labels = new Label[pros.Length + 1]; for (var i = 0; i < pros.Length; i++) { labels[i] = ilGenerator.DefineLabel(); } labels[pros.Length] = retLabel; for (var i = 0; i < pros.Length; i++) { var property = pros[i]; ilGenerator.MarkLabel(labels[i]); ilGenerator.Emit(OpCodes.Ldarg_2); var proName = property.Name; ilGenerator.Emit(OpCodes.Ldstr, proName); ilGenerator.EmitCall(OpCodes.Call, compareStringMethod, new[] { typeof(string), typeof(string) }); ilGenerator.Emit(OpCodes.Brfalse, labels[i + 1]); ilGenerator.Emit(OpCodes.Nop); ilGenerator.Emit(OpCodes.Ldarg_1); EmitHelper.LoadType(ilGenerator, property.PropertyType); ilGenerator.Emit(OpCodes.Ldarg_3); ilGenerator.EmitCall(OpCodes.Call, changeTypeMethod, new[] { typeof(Type), typeof(object) }); //先将object转换到正确的类型,即使还是一个object #region 类型转换 这一段是必须的,否则会导致内存状态损坏 //注意:TypeUtil.ChangeType返回的是object。 if (property.PropertyType.IsValueType) //值类型,则拆箱 { ilGenerator.Emit(OpCodes.Unbox_Any, property.PropertyType); } else if (property.PropertyType == typeof(byte[]) || property.PropertyType == typeof(string)) { ilGenerator.Emit(OpCodes.Castclass, property.PropertyType); } else if (property.PropertyType == typeof(object) || property.PropertyType.IsClass || property.PropertyType.IsGenericType) { //do nothing .对应sql_variant } else { var toStringMethod = typeof(object).GetMethod("ToString"); ilGenerator.EmitCall(OpCodes.Callvirt, toStringMethod, null); //类型转换 if (property.PropertyType != typeof(string)) { var parseMethod = property.PropertyType.GetMethod("Parse", new[] { typeof(string) }); ilGenerator.EmitCall(OpCodes.Callvirt, parseMethod, new[] { typeof(string) }); } } #endregion var setPropertyMethod = entityType.GetMethod("set_" + proName, new[] { property.PropertyType }); if (entityType.IsValueType) { ilGenerator.EmitCall(OpCodes.Call, setPropertyMethod, new[] { property.PropertyType }); } else { ilGenerator.EmitCall(OpCodes.Callvirt, setPropertyMethod, new[] { property.PropertyType }); } ilGenerator.Emit(OpCodes.Br, retLabel); } ilGenerator.MarkLabel(retLabel); ilGenerator.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodBuilder, baseMethod); }
private void EmitGetValueMethod(TypeBuilder typeBuilder, MethodInfo baseMethod, Type entityType, MethodInfo getPropertyValueMethod) { var methodBuilder = typeBuilder.DefineMethod("GetValue", baseMethod.Attributes & ~MethodAttributes.Abstract, baseMethod.CallingConvention, baseMethod.ReturnType, EmitHelper.GetParametersType(baseMethod)); var ilGenerator = methodBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldarg_1); if (entityType.IsValueType) { ilGenerator.Emit(OpCodes.Unbox_Any, entityType); } else { ilGenerator.Emit(OpCodes.Castclass, entityType); } ilGenerator.Emit(OpCodes.Ldarg_2); ilGenerator.Emit(OpCodes.Callvirt, getPropertyValueMethod); ilGenerator.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodBuilder, baseMethod); }
private void EmitGetPropertyValueMethod(TypeBuilder typeBuilder, MethodInfo baseMethod, Type entityType) { var methodBuilder = typeBuilder.DefineMethod("GetPropertyValue", baseMethod.Attributes & ~MethodAttributes.Abstract, baseMethod.CallingConvention, baseMethod.ReturnType, EmitHelper.GetParametersType(baseMethod)); var compareStringMethod = typeof(string).GetMethod("op_Equality", new[] { typeof(string), typeof(string) }); var ilGenerator = methodBuilder.GetILGenerator(); ilGenerator.DeclareLocal(typeof(object)); ilGenerator.Emit(OpCodes.Nop); var tempPros = entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags .GetProperty); // ESBasic.Helpers.TypeUtil.ConvertListToArray<PropertyInfo>(columnList); IList <PropertyInfo> proList = new List <PropertyInfo>(); foreach (var propertyInfo in tempPros) { if (propertyInfo.CanWrite && propertyInfo.CanRead) { proList.Add(propertyInfo); } } var pros = proList.ToArray(); var loadNullLabel = ilGenerator.DefineLabel(); var retLabel = ilGenerator.DefineLabel(); var labels = new Label[pros.Length + 1]; for (var i = 0; i < pros.Length; i++) { labels[i] = ilGenerator.DefineLabel(); } labels[pros.Length] = loadNullLabel; for (var i = 0; i < pros.Length; i++) { var property = pros[i]; ilGenerator.MarkLabel(labels[i]); ilGenerator.Emit(OpCodes.Ldarg_2); var proName = property.Name; ilGenerator.Emit(OpCodes.Ldstr, proName); ilGenerator.EmitCall(OpCodes.Call, compareStringMethod, new[] { typeof(string), typeof(string) }); ilGenerator.Emit(OpCodes.Brfalse, labels[i + 1]); ilGenerator.Emit(OpCodes.Nop); if (entityType.IsValueType) { ilGenerator.Emit(OpCodes.Ldarga, 1); } else { ilGenerator.Emit(OpCodes.Ldarg_1); } var getPropertyMethod = entityType.GetMethod("get_" + proName, new Type[] { }); if (entityType.IsValueType) { ilGenerator.EmitCall(OpCodes.Call, getPropertyMethod, new Type[] { }); } else { ilGenerator.EmitCall(OpCodes.Callvirt, getPropertyMethod, new Type[] { }); } if (property.PropertyType.IsValueType) { ilGenerator.Emit(OpCodes.Box, property.PropertyType); } ilGenerator.Emit(OpCodes.Stloc_0); ilGenerator.Emit(OpCodes.Br, retLabel); } ilGenerator.MarkLabel(loadNullLabel); ilGenerator.Emit(OpCodes.Ldnull); ilGenerator.Emit(OpCodes.Stloc_0); ilGenerator.Emit(OpCodes.Br, retLabel); ilGenerator.MarkLabel(retLabel); ilGenerator.Emit(OpCodes.Ldloc_0); ilGenerator.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodBuilder, baseMethod); }