예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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));
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }