Пример #1
0
        private void Prepare(IDataRecord dataRecord)
        {
            // 定义一个动态方法,返回类型 typeof(T),输入类型 typeof(IDataRecord)
            Type          type = typeof(T);
            string        name = string.Format("Create{0}", type.Name);
            DynamicMethod dynamicMethod;

            if (DynamicMethodContainer.IsExist(name))
            {
                dynamicMethod = DynamicMethodContainer.Get(name);
            }
            else
            {
                Dictionary <string, int> dictionary = Match(dataRecord);

                dynamicMethod = new DynamicMethod(
                    name,
                    type,
                    new Type[] { typeof(IDataRecord) },
                    type,
                    true);

                // 创建一个MSIL生成器,为动态方法生成代码
                ILGenerator generator = dynamicMethod.GetILGenerator();

                // 声明指定类型的局部变量,可以理解为 T t;
                LocalBuilder localBuilder = generator.DeclareLocal(type);

                // 可以理解为 T t = new T(); The next piece of code instantiates the requested type of object and stores it in the local variable.
                ConstructorInfo constructorInfo = type.GetConstructor(Type.EmptyTypes);
                generator.Emit(OpCodes.Newobj, constructorInfo);
                generator.Emit(OpCodes.Stloc, localBuilder);

                foreach (string propertyName in dictionary.Keys)
                {
                    PropertyInfo propertyInfo = type.GetProperty(propertyName);
                    int          index        = dictionary[propertyName];

                    // 定义标签
                    Label endIfLabel = generator.DefineLabel();

                    generator.Emit(OpCodes.Ldarg_0);
                    generator.Emit(OpCodes.Ldc_I4, index);

                    // 调用 Callvirt : dataRecord.IsDBNull() 方法
                    generator.Emit(OpCodes.Callvirt, isDBNullMethod);
                    // 如果是 DataRecord.IsDBNull() == true 则 contine
                    generator.Emit(OpCodes.Brtrue, endIfLabel);

                    generator.Emit(OpCodes.Ldloc, localBuilder);
                    generator.Emit(OpCodes.Ldarg_0);
                    generator.Emit(OpCodes.Ldc_I4, index);

                    // 调用 Callvirt : dataRecord.get_Item(i) 方法
                    generator.Emit(OpCodes.Callvirt, getItemMethod);
                    generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(index));

                    // 调用 Callvirt : propertyInfo.GetSetMethod 方法
                    generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());

                    // 在当前 MSIL 流位置进行标记
                    generator.MarkLabel(endIfLabel);
                }

                // The last part of the code returns the value of the local variable
                generator.Emit(OpCodes.Ldloc, localBuilder);

                // 方法结束
                generator.Emit(OpCodes.Ret);

                DynamicMethodContainer.Add(name, dynamicMethod);
            }

            // 完成动态方法的创建并创建执行该动态方法的委托
            // DataRecord2Entity 在 Build 方法里实现
            this.dataRecord2Entity = (DataRecord2Entity)dynamicMethod.CreateDelegate(typeof(DataRecord2Entity));
        }
Пример #2
0
        /// 定义一个动态方法,返回类型 typeof(T),输入类型 typeof(IDataRecord)
        /// <remarks>
        /// if (DynamicMethodContainer.IsExist(name))
        /// {
        ///     DynamicMethod dynamicMethod = DynamicMethodContainer.Get(name);
        /// }
        /// else
        /// {
        ///     DynamicMethodContainer.Add(name, dynamicMethod);
        /// }
        /// </remarks>
        protected void PrepareDelegate(IDataRecord dataRecord)
        {
            string name = string.Format("Create{0}", this.type.Name);

            Type[]        parameterTypes = new Type[] { typeof(IDataRecord) };
            DynamicMethod dynamicMethod  = new DynamicMethod(name, this.type, parameterTypes, this.type, true);

            // 创建一个MSIL生成器,为动态方法生成代码
            ILGenerator generator = dynamicMethod.GetILGenerator();

            // 声明指定类型的局部变量,可以理解为 T t;
            LocalBuilder localBuilder = generator.DeclareLocal(this.type);

            // PUSH : T t = new T();
            // Instantiates the requested type of object and stores it in the local variable.
            ConstructorInfo constructorInfo = type.GetConstructor(Type.EmptyTypes);

            generator.Emit(OpCodes.Newobj, constructorInfo);
            generator.Emit(OpCodes.Stloc, localBuilder);

            Dictionary <int, string> dictionary = this.Match(dataRecord);

            foreach (int i in dictionary.Keys)
            {
                string       propertyName = dictionary[i];
                PropertyInfo propertyInfo = this.type.GetProperty(propertyName);

                // 定义标签
                Label endIfLabel = generator.DefineLabel();

                // 调用 Callvirt : IDataRecord.IsDBNull() 方法
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldc_I4, i);
                generator.Emit(OpCodes.Callvirt, IsDBNullMethod);
                // 如果是 DataRecord.IsDBNull() == true 则 contine
                generator.Emit(OpCodes.Brtrue, endIfLabel);

                // POP : T t
                generator.Emit(OpCodes.Ldloc, localBuilder);

                // 调用 Callvirt : IDataRecord.get_Item(i) 方法
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldc_I4, i);
                generator.Emit(OpCodes.Callvirt, getItemMethod);

                //Ad By RQ 2011-01-18 12:46 ORACLE DATE 用 dataRecord.GetFieldType(i) 得出的类型转换出错
                //generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i));

                generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);

                // 调用 Callvirt : propertyInfo.GetSetMethod 方法
                generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());

                // 在当前 MSIL 流位置进行标记
                generator.MarkLabel(endIfLabel);
            }

            // returns the value of the local variable
            generator.Emit(OpCodes.Ldloc, localBuilder);

            // 方法结束
            generator.Emit(OpCodes.Ret);

            // 完成动态方法的创建并创建执行该动态方法的委托
            this.dataRecord2Entity = (DataRecord2Entity)dynamicMethod.CreateDelegate(typeof(DataRecord2Entity));
        }