//DataReader로 부터 값들을 읽어 인스턴스를 만든다 private ConstructInstance CreateConstructInstance(IDataReader reader) { ParameterException.Check(reader != null, ParameterError.NotExistReader); var type = typeof(T); var dynamicMethod = new DynamicMethod("ConstructInstance", type, new[] { typeof(IDataReader) }, type); var il = dynamicMethod.GetILGenerator(); Label startLoop = il.DefineLabel(); Label endLoop = il.DefineLabel(); ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); il.Emit(OpCodes.Newobj, constructor); //[instance] il.MarkLabel(startLoop); PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (PropertyInfo property in properties) { Label startValueTypeNullLoop = il.DefineLabel(); Label endValueTypeNullLoop = il.DefineLabel(); Label jumpToEnd = il.DefineLabel(); var columnAttribute = property.GetCustomAttribute <ColumnAttribute>(); AttributeException.Check(columnAttribute != null, AttributeError.NotExistColumnAttribute); var columnName = columnAttribute.Name ?? property.Name; //SetValue il.Emit(OpCodes.Dup); //[instance][instance] il.Emit(OpCodes.Ldarg_0); //[instance][instance][IDataReader] il.Emit(OpCodes.Ldstr, columnName); //[instance][instance][IDataReader][Name] il.Emit(OpCodes.Call, typeof(IDataReaderHelper).GetMethod(nameof(IDataReaderHelper .GetValue))); //[instance][instance][value] il.Emit(OpCodes.Dup); //[instance][instance][value][value] il.Emit(OpCodes.Ldsfld, typeof(DBNull).GetField(nameof(DBNull.Value))); //[instance][instance][value][value][DBNullValue] il.Emit(OpCodes.Ceq); // [instance][instance][value][result] il.Emit(OpCodes.Brtrue, startValueTypeNullLoop); //[instance][instance] if (property.PropertyType.IsValueType) { il.Emit(OpCodes.Unbox_Any, property.PropertyType); //[instance][instance][unbox_value] } il.MarkLabel(endValueTypeNullLoop); il.Emit(OpCodes.Call, property.GetSetMethod()); //[instance] il.Emit(OpCodes.Br, jumpToEnd); il.MarkLabel(startValueTypeNullLoop); if (property.PropertyType.IsValueType) { il.Emit(OpCodes.Pop); //[instance][instance] il.Emit(OpCodes.Ldc_I4_0); //[instance][instance][0] } il.Emit(OpCodes.Br, endValueTypeNullLoop); il.MarkLabel(jumpToEnd); } il.MarkLabel(endLoop); il.Emit(OpCodes.Ret); return((ConstructInstance)dynamicMethod.CreateDelegate(typeof(ConstructInstance))); }