private void CreateUpdateFunction(Type type, TypeBuilderHelper typeBuilderHelper) { var classMetadata = ClassMetaDataManager.Instace.GetClassMetaData(type); var properties = classMetadata.Properties; var mappingTable = classMetadata.MappingTable; var methodEmit = typeBuilderHelper.DefineMethod(typeof (IDbFunctionHelper).GetMethod("Update")).Emitter; var resultLocal = methodEmit.DeclareLocal(typeof (int)); var commandLocal = methodEmit.DeclareLocal(typeof (DbCommand)); var commandParameters = methodEmit.DeclareLocal(typeof (DbParameterCollection)); var queryBuilder = new StringBuilder("UPDATE " + mappingTable + " SET "); var objectNotDirtyLabel = methodEmit.DefineLabel(); foreach (var mappingInfo in properties.Values) { if (mappingInfo.MappingField != "Id") { queryBuilder.Append(mappingInfo.MappingField + "=@" + mappingInfo.MappingField + ", "); } } var tmpString = queryBuilder.ToString(0, queryBuilder.Length - 2); queryBuilder.Length = 0; queryBuilder.Append(tmpString); queryBuilder.Append(" WHERE Id = @Id"); methodEmit .ldarg_1 .call(typeof(IDbObject).GetMethod("get_IsDirty")) .brfalse(objectNotDirtyLabel) .ldc_i4_0 .stloc(resultLocal) .ldarg_2 .call(typeof(DbConnection).GetMethod("CreateCommand")) .stloc(commandLocal) .ldloc(commandLocal) .ldstr(queryBuilder.ToString()) .call(typeof(DbCommand).GetMethod("set_CommandText")) .ldloc(commandLocal) .call(typeof(DbCommand).GetMethod("get_Parameters")) .stloc(commandParameters); foreach (var mappingInfo in properties.Values) { var propertyInfo = mappingInfo.PropertyInfo; var mappingField = mappingInfo.MappingField; var propertyType = propertyInfo.PropertyType; if (propertyType.IsPrimitive || propertyType == typeof(string) || propertyType == typeof(DateTime) || propertyType == typeof(decimal)) { methodEmit .ldloc(commandParameters) .ldstr("@" + mappingField) //Param 1 for MySqlParameter constructor .ldarg_1 .call(propertyInfo.GetGetMethod()) //Param 2 for MySqlParameter constructor .newobj(typeof (MySqlParameter), typeof (string), typeof (object)) // Param for Add of DbParameterCollection .call(typeof (DbParameterCollection).GetMethod("Add", new[] {typeof (object)})) ; } else //Property that need to be convert to byte array before set { var propetyValueLocal = methodEmit.DeclareLocal(propertyType); var dbSerializerHelperLocal = methodEmit.DeclareLocal(typeof (DbSerializerHelper)); var memoryStreamLocal = methodEmit.DeclareLocal(typeof (MemoryStream)); var propertyByteArray = methodEmit.DeclareLocal(typeof (byte[])); methodEmit .ldarg_1 .call(propertyInfo.GetGetMethod()) .stloc(propetyValueLocal) .newobj(typeof(MemoryStream), Type.EmptyTypes) .stloc(memoryStreamLocal); methodEmit.BeginExceptionBlock(); methodEmit .ldloc(memoryStreamLocal) .newobj(typeof(BinaryWriter), typeof(Stream)) .newobj(typeof(DbSerializerHelper), typeof(BinaryWriter)) .stloc(dbSerializerHelperLocal) .ldloc(dbSerializerHelperLocal) .ldarg_1 .call(propertyInfo.GetGetMethod()) .call(typeof(DbSerializerHelper).GetMethod("Write", new[] {propertyType})) .ldloc(memoryStreamLocal) .call(typeof(MemoryStream).GetMethod("ToArray")) .stloc(propertyByteArray) .ldloc(commandParameters) .ldstr("@" + mappingField) .ldloc(propertyByteArray) .newobj(typeof(MySqlParameter), typeof(string), typeof(object)) // Param for Add of DbParameterCollection .call(typeof(DbParameterCollection).GetMethod("Add", new[] { typeof(object) })) .BeginFinallyBlock() .ldloc(memoryStreamLocal) .call(typeof(IDisposable).GetMethod("Dispose")) .EndExceptionBlock() ; } } methodEmit .ldloc(commandLocal) .call(typeof(DbCommand).GetMethod("ExecuteNonQuery")) .stloc(resultLocal) .ldarg_1 .ldc_bool(false) .call(typeof(IDbObject).GetMethod("set_IsDirty")) .MarkLabel(objectNotDirtyLabel); //Update relation var relations = classMetadata.RelationProperties; LocalBuilder queryExecutorLocal = null; if (relations.Count > 0) { queryExecutorLocal = methodEmit.DeclareLocal(typeof (IQueryExecutor)); var dbObjectContainerField = typeBuilderHelper.TypeBuilder.GetField("dbObjectContainer"); methodEmit .ldfld(dbObjectContainerField) .call(typeof (DbObjectContainer).GetMethod("get_QueryExecutor")) .stloc(queryExecutorLocal); } foreach (var relationInfo in relations.Values) { var propertyInfo = relationInfo.PropertyInfo; var propertyType = propertyInfo.PropertyType; var elementType = propertyType.IsGenericType ? propertyType.GetGenericArguments()[0] : propertyType; var listPersistentDbObjectLocal = methodEmit.DeclareLocal(typeof(IList<long>)); var listCurrentType = typeof (List<>).MakeGenericType(elementType); var addElementMethod = typeof (ICollection<>).MakeGenericType(elementType).GetMethod("Add"); var countElementMethod = typeof (ICollection<>).MakeGenericType(elementType).GetMethod("Count"); var listConstructorMethod = listCurrentType.GetConstructor(new[] {typeof (IEnumerable<>).MakeGenericType(elementType)}); var listCurrentDbObjectLocal = methodEmit.DeclareLocal(listCurrentType); var mappingColumn = relationInfo.PartnerKey; var relationCommandLocal = methodEmit.DeclareLocal(typeof (DbCommand)); var readerLocal = methodEmit.DeclareLocal(typeof (DbDataReader)); var relationTimeInfoLocal = methodEmit.DeclareLocal(typeof (TimeRelationInfo)); var commandText = "SELECT " + mappingColumn + " FROM " + mappingTable + " WHERE Id = @Id"; methodEmit .ldarg_2 .call(typeof (DbConnection).GetMethod("CreateCommand")) .stloc(relationCommandLocal) .ldloc(relationCommandLocal) .ldstr(commandText) .call(typeof (DbCommand).GetMethod("set_CommandText")) .ldloc(relationCommandLocal) .call(typeof(DbCommand).GetMethod("ExecuteReader")) .stloc(readerLocal) .ldstr(mappingColumn) .ldloc(readerLocal) .call(typeof(DbSerializerHelper).GetMethod("ReadRelationTimeInfo")) .stloc(relationTimeInfoLocal) .ldloc(relationTimeInfoLocal) .ldfld(typeof(TimeRelationInfo).GetField("idList")) .stloc(listPersistentDbObjectLocal) ; if (relationInfo.RelationKind == RelationInfo.RELATION_1_1) { methodEmit .newobj(listCurrentType, Type.EmptyTypes) .stloc(listCurrentDbObjectLocal) .ldloc(listCurrentDbObjectLocal) .ldarg_1 .call(propertyInfo.GetGetMethod()) .call(addElementMethod) ; } else { methodEmit .ldarg_1 .call(propertyInfo.GetGetMethod()) .newobj(listConstructorMethod) .stloc(listCurrentDbObjectLocal) ; } var lenLocal = methodEmit.DeclareLocal(typeof (int)); var iLocal = methodEmit.DeclareLocal(typeof (int)); var beginForLabel = methodEmit.DefineLabel(); var beginForBodyLabel = methodEmit.DefineLabel(); var itemLocal = methodEmit.DeclareLocal(elementType); var itemIdLocal = methodEmit.DeclareLocal(typeof (long)); var itemNullLabel = methodEmit.DefineLabel(); var getCurrentObjectElementMethod = listCurrentType.GetMethod("get_Item", new[] {typeof (int)}); var listPersistentContainCurrentElementLabel = methodEmit.DefineLabel(); var listPersistentNotContainCurrentElementLabel = methodEmit.DefineLabel(); methodEmit .ldloc(listCurrentDbObjectLocal) .call(countElementMethod) .stloc(lenLocal) .ldc_i4_0 .stloc(iLocal) .br(beginForLabel) .MarkLabel(beginForBodyLabel) .ldloc(listCurrentDbObjectLocal) .ldloc(iLocal) .call(getCurrentObjectElementMethod) .stloc(itemLocal) .ldloc(itemLocal) .brfalse(itemNullLabel) .ldloc(itemLocal) .call(typeof(IDbObject).GetMethod("get_Id")) .stloc(itemIdLocal) .ldloc(listPersistentDbObjectLocal) .ldloc(itemIdLocal) .call(typeof(ICollection<long>).GetMethod("Contain")) .brtrue(listPersistentContainCurrentElementLabel) .ldloc(queryExecutorLocal) .ldloc(itemLocal) .ldnull .call(typeof(IQueryExecutor).GetMethod("Insert", new[] { typeof(IDbObject), typeof(IsolationLevel?), typeof(long), typeof(string) })) .br(listPersistentNotContainCurrentElementLabel) .MarkLabel(listPersistentContainCurrentElementLabel) .MarkLabel(listPersistentNotContainCurrentElementLabel) .MarkLabel(itemNullLabel) .ldloc(iLocal) .ldc_i4_1 .add .stloc(iLocal) .MarkLabel(beginForLabel) .ldloc(iLocal) .ldloc(lenLocal) .blt(beginForBodyLabel) ; } }
/// <summary> /// All interface methods are implemented in the generated class in here /// </summary> /// <param name="logicField"></param> /// <param name="logicClass"></param> /// <param name="mDataInferface"></param> /// <param name="type"></param> private void MapMethods(FieldInfo logicField, Type logicClass, Type mDataInferface, TypeBuilderHelper type) { //loop all methods of the interface definition foreach (var methodInfo in mDataInferface.GetMethods()) { //only implement Methods if (methodInfo.MemberType != MemberTypes.Method) continue; //get_ and set_ methods are special cases, implement them as properties if (methodInfo.Name.StartsWith("get_") || methodInfo.Name.StartsWith("set_")) continue; //get method parameters and generic arguments var methodParameters = methodInfo.GetParameters(); var methodGenericArguments = methodInfo.GetGenericArguments(); MethodBuilderHelper methodBuilder; //check if we got to define a generic method or not if (methodGenericArguments.Length > 0) { methodBuilder = type.DefineGenericMethod(methodInfo.Name, MethodAttributes.Virtual | MethodAttributes.Public, CallingConventions.Standard, methodGenericArguments, methodInfo.ReturnType, methodParameters.Select(x => x.ParameterType).ToArray()); } else { methodBuilder = type.DefineMethod(methodInfo.Name, MethodAttributes.Virtual | MethodAttributes.Public, methodInfo.ReturnType, methodParameters.Select(x => x.ParameterType).ToArray()); } //get hold of the method emitter var emit = methodBuilder.Emitter; if (methodParameters.Any()) emit.DeclareLocal(typeof (object[])); //load 'this' instance emit .ldarg(0) .ldfld(logicField); var logicMethod = GetLogicMethod(logicClass, methodInfo); //logicmethod == null so we have to call UnImplemented*MethodCall function if (logicMethod == null) { logicMethod = methodInfo.ReturnType == typeof (void) ? Reflect<LogicBase>.GetMethod(x=>x.UnImplementedNoReturnMethodCall(string.Empty)) : Reflect<LogicBase>.GetMethod(x => x.UnImplementedMethodCall<object>(string.Empty)).MakeGenericMethod(methodInfo.ReturnType); //we store the parameters in a new object[] so we can pass them to the UnImpl methods emit = emit .ldc_i4_(methodParameters.Count()) .newarr(typeof (object)); if (methodParameters.Any()) { emit = emit.stloc_0; for (var index = 0; index < methodParameters.Length; index++) { emit .ldloc_0 .ldc_i4_(index) .ldarg(index + 1); //box value type (int, etc) and generic parameter (e.g. 'T') if (methodParameters[index].ParameterType.IsValueType || methodParameters[index].ParameterType.IsGenericParameter) emit.box(methodParameters[index].ParameterType); //store the first stack element in the array defined in the upper stack emit = emit .stelem_ref; } //load method name emit = emit .ldstr(methodInfo.Name) .ldloc_0; } else emit.ldstr(methodInfo.Name); } else { //load all method parameters onto stack foreach (var parameterInfo in methodParameters) { emit.ldarg(parameterInfo); } } //call the logic class emit .callvirt(logicMethod) .ret(); } }
private void CreateProperty(TypeBuilderHelper typeBuilderHelper) { var dbObjectContainerField = typeBuilderHelper.DefineField("dbObjectContainer", typeof (DbObjectContainer), FieldAttributes.Private); var objectContainerProperty = typeBuilderHelper.TypeBuilder.DefineProperty("DbObjectContainer", PropertyAttributes.HasDefault, typeof (DbObjectContainer), new[] { typeof(DbObjectContainer) }); var attributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; var objectContainerGetMethod = typeBuilderHelper.DefineMethod("get_DbObjectContainer", attributes, typeof(DbObjectContainer), Type.EmptyTypes); var objectContainerGetMethodEmit = objectContainerGetMethod.Emitter; objectContainerGetMethodEmit .ldarg_0 .ldfld(dbObjectContainerField) .ret(); var objectContainerSetMethod = typeBuilderHelper.DefineMethod("set_DbObjectContainer", attributes, null, typeof(DbObjectContainer)); var objectContainerSetMethodEmit = objectContainerSetMethod.Emitter; objectContainerSetMethodEmit .ldarg_0 .ldarg_1 .stfld(dbObjectContainerField) .ret(); objectContainerProperty.SetGetMethod(objectContainerGetMethod); objectContainerProperty.SetSetMethod(objectContainerSetMethod); }
/// <summary> /// Creates the body of a property getter /// </summary> /// <param name="generatedTypeBuilder"></param> /// <param name="p"></param> /// <param name="property"></param> /// <param name="getDecl"></param> /// <param name="logicField"></param> private void CreatePropertyGetMethod(TypeBuilderHelper generatedTypeBuilder, PropertyInfo p, PropertyBuilder property, MethodInfo getDecl, FieldInfo logicField) { //set setter name and return type var setterName = getDecl == null ? "get_" + p.Name : getDecl.Name; var returnType = getDecl == null ? p.PropertyType : getDecl.ReturnType; //determine security attributes var methodAttributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual; //create setter method var getBuilder = generatedTypeBuilder.DefineMethod(setterName, methodAttributes, returnType, null); //emit IL opcode getBuilder .Emitter .nop .ldarg_0 .ldfld(logicField) .ldstr(p.Name) //this.LogicBase<[logicField.FieldType]>.GetProperty([methodName]) .callvirt(Reflect<LogicBase>.GetMethod(x => x.GetProperty<object>(string.Empty)).MakeGenericMethod(p.PropertyType)) .ret(); //apply the created method to the getter property.SetGetMethod(getBuilder); }
/// <summary> /// Creates the body of a property setter /// </summary> /// <param name="generatedTypeBuilder"></param> /// <param name="p"></param> /// <param name="property"></param> /// <param name="setDecl"></param> /// <param name="logicField"></param> private void CreatePropertySetMethod(TypeBuilderHelper generatedTypeBuilder, PropertyInfo p, PropertyBuilder property, MethodInfo setDecl, FieldInfo logicField) { //set getter name and parameter types var name = setDecl == null ? "set_" + p.Name : setDecl.Name; var parameterTypes = setDecl == null ? new[] { p.PropertyType } : setDecl.GetParameters().Select(x => x.ParameterType).ToArray(); //set attributes on setter var methodAttributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual; //build setter method var setBuilder = generatedTypeBuilder.DefineMethod(name, methodAttributes, null, parameterTypes); //spit out IL setBuilder .Emitter .ldarg_0 .ldfld(logicField) .ldstr(p.Name) .ldarg_1 .callvirt(Reflect<LogicBase>.GetMethod(x=> x.SetProperty(string.Empty, string.Empty)).MakeGenericMethod(p.PropertyType)) .nop .ret(); //apply setter method to the property property.SetSetMethod(setBuilder); }
private void BuildTypedGetterForNullable( MemberInfo mi, TypeBuilderHelper nestedType, Type memberType) { Type methodType = mi.DeclaringType; MethodInfo getMethod = null; if (mi is PropertyInfo) { getMethod = ((PropertyInfo)mi).GetGetMethod(); if (getMethod == null) { if (_type != _originalType) { getMethod = _type.GetMethod("get_" + mi.Name); methodType = _type; } if (getMethod == null || !IsMethodAccessible(getMethod)) return; } } Type setterType = (memberType.IsEnum ? Enum.GetUnderlyingType(memberType) : memberType); MethodInfo methodInfo = _memberAccessor.GetMethod("Get" + setterType.Name, typeof(object)); if (methodInfo == null) return; MethodBuilderHelper method = nestedType.DefineMethod(methodInfo); Type nullableType = typeof(Nullable<>).MakeGenericType(memberType); LocalBuilder locObj = method.Emitter.DeclareLocal(nullableType); EmitHelper emit = method.Emitter; emit .ldarg_1 .castType (methodType) .end(); if (mi is FieldInfo) emit.ldfld ((FieldInfo)mi); else emit.callvirt(getMethod); emit .stloc(locObj) .ldloca(locObj) .call(nullableType, "get_Value") .ret() ; }
private void BuildTypedSetterForNullable( MemberInfo mi, TypeBuilderHelper nestedType, Type memberType) { Type methodType = mi.DeclaringType; MethodInfo setMethod = null; if (mi is PropertyInfo) { setMethod = ((PropertyInfo)mi).GetSetMethod(); if (setMethod == null) { if (_type != _originalType) { setMethod = _type.GetMethod("set_" + mi.Name); methodType = _type; } if (setMethod == null || !IsMethodAccessible(setMethod)) return; } } Type setterType = (memberType.IsEnum ? Enum.GetUnderlyingType(memberType) : memberType); MethodInfo methodInfo = _memberAccessor.GetMethod("Set" + setterType.Name, typeof(object), setterType); if (methodInfo == null) return; MethodBuilderHelper method = nestedType.DefineMethod(methodInfo); EmitHelper emit = method.Emitter; emit .ldarg_1 .castType (methodType) .ldarg_2 .newobj (typeof(Nullable<>).MakeGenericType(memberType), memberType) .end(); if (mi is FieldInfo) emit.stfld ((FieldInfo)mi); else emit.callvirt(setMethod); emit .ret() ; }
private void BuildCloneValueMethod( MemberInfo mi, TypeBuilderHelper nestedType, Type memberType ) { Type methodType = mi.DeclaringType; MethodInfo getMethod = null; MethodInfo setMethod = null; if (mi is PropertyInfo) { getMethod = ((PropertyInfo)mi).GetGetMethod(); if (getMethod == null) { if (_type != _originalType) { getMethod = _type.GetMethod("get_" + mi.Name); methodType = _type; } if (getMethod == null || !IsMethodAccessible(getMethod)) return; } setMethod = ((PropertyInfo)mi).GetSetMethod(); if (setMethod == null) { if (_type != _originalType) { setMethod = _type.GetMethod("set_" + mi.Name); methodType = _type; } if (setMethod == null || !IsMethodAccessible(setMethod)) return; } } MethodBuilderHelper method = nestedType.DefineMethod( _memberAccessor.GetMethod("CloneValue", typeof(object), typeof(object))); EmitHelper emit = method.Emitter; emit .ldarg_2 .castType (methodType) .ldarg_1 .castType (methodType) .end(); if (mi is FieldInfo) emit.ldfld ((FieldInfo)mi); else emit.callvirt(getMethod); if (typeof(string) != memberType && TypeHelper.IsSameOrParent(typeof(ICloneable), memberType)) { if (memberType.IsValueType) emit .box (memberType) .callvirt (typeof(ICloneable), "Clone") .unbox_any (memberType) ; else { Label valueIsNull = emit.DefineLabel(); emit .dup .brfalse_s (valueIsNull) .callvirt (typeof(ICloneable), "Clone") .castclass (memberType) .MarkLabel (valueIsNull) ; } } if (mi is FieldInfo) emit.stfld ((FieldInfo)mi); else emit.callvirt(setMethod); emit .ret() ; }
private void BuildTypedSetter( MemberInfo mi, TypeBuilderHelper nestedType, Type memberType, string typedPropertyName) { Type methodType = mi.DeclaringType; MethodInfo setMethod = null; if (mi is PropertyInfo) { setMethod = ((PropertyInfo)mi).GetSetMethod(); if (setMethod == null) { if (_type != _originalType) { setMethod = _type.GetMethod("set_" + mi.Name); methodType = _type; } if (setMethod == null || !IsMethodAccessible(setMethod)) return; } } MethodInfo methodInfo = _memberAccessor.GetMethod("Set" + typedPropertyName, typeof(object), memberType); if (methodInfo == null) return; MethodBuilderHelper method = nestedType.DefineMethod(methodInfo); EmitHelper emit = method.Emitter; emit .ldarg_1 .castType (methodType) .ldarg_2 .end(); if (mi is FieldInfo) emit.stfld ((FieldInfo)mi); else emit.callvirt(setMethod); emit .ret() ; }
private void BuildIsNull( MemberInfo mi, TypeBuilderHelper nestedType, Type memberType) { Type methodType = mi.DeclaringType; MethodInfo getMethod = null; Boolean isNullable = TypeHelper.IsNullable(memberType); Boolean isValueType = (!isNullable && memberType.IsValueType); if (!isValueType && mi is PropertyInfo) { getMethod = ((PropertyInfo)mi).GetGetMethod(); if (getMethod == null) { if (_type != _originalType) { getMethod = _type.GetMethod("get_" + mi.Name); methodType = _type; } if (getMethod == null) return; } } MethodInfo methodInfo = _memberAccessor.GetMethod("IsNull"); if (methodInfo == null) return; MethodBuilderHelper method = nestedType.DefineMethod(methodInfo); EmitHelper emit = method.Emitter; if (isValueType) { emit .ldc_i4_0 .end() ; } else { LocalBuilder locObj = null; if (isNullable) locObj = method.Emitter.DeclareLocal(memberType); emit .ldarg_1 .castType (methodType) .end(); if (mi is FieldInfo) emit.ldfld ((FieldInfo)mi); else emit.callvirt(getMethod); if (isNullable) { emit .stloc(locObj) .ldloca(locObj) .call(memberType, "get_HasValue") .ldc_i4_0 .ceq .end(); } else { emit .ldnull .ceq .end(); } } emit .ret() ; }
private void BuildSetter(MemberInfo mi, TypeBuilderHelper nestedType) { Type methodType = mi.DeclaringType; MethodInfo setMethod = null; if (mi is PropertyInfo) { setMethod = ((PropertyInfo)mi).GetSetMethod(); if (setMethod == null) { if (_type != _originalType) { setMethod = _type.GetMethod("set_" + mi.Name); methodType = _type; } if (setMethod == null || !IsMethodAccessible(setMethod)) return; } } //else if (((FieldInfo)mi).IsLiteral) // return; MethodBuilderHelper method = nestedType.DefineMethod( _memberAccessor.GetMethod("SetValue", typeof(object), typeof(object))); EmitHelper emit = method.Emitter; emit .ldarg_1 .castType (methodType) .ldarg_2 .end(); if (mi is FieldInfo) { FieldInfo fi = (FieldInfo)mi; emit .CastFromObject (fi.FieldType) .stfld (fi) ; } else { PropertyInfo pi = (PropertyInfo)mi; emit .CastFromObject (pi.PropertyType) .callvirt (setMethod) ; } emit .ret() ; nestedType.DefineMethod(_memberAccessor.GetProperty("HasSetter").GetGetMethod()).Emitter .ldc_i4_1 .ret() ; }
private void BuildGetter(MemberInfo mi, TypeBuilderHelper nestedType) { Type methodType = mi.DeclaringType; MethodInfo getMethod = null; if (mi is PropertyInfo) { getMethod = ((PropertyInfo)mi).GetGetMethod(); if (getMethod == null) { if (_type != _originalType) { getMethod = _type.GetMethod("get_" + mi.Name); methodType = _type; } if (getMethod == null || !IsMethodAccessible(getMethod)) return; } } MethodBuilderHelper method = nestedType.DefineMethod( _memberAccessor.GetMethod("GetValue", typeof(object))); EmitHelper emit = method.Emitter; emit .ldarg_1 .castType (methodType) .end(); if (mi is FieldInfo) { FieldInfo fi = (FieldInfo)mi; emit .ldfld (fi) .boxIfValueType (fi.FieldType) ; } else { PropertyInfo pi = (PropertyInfo)mi; emit .callvirt (getMethod) .boxIfValueType (pi.PropertyType) ; } emit .ret() ; nestedType.DefineMethod(_memberAccessor.GetProperty("HasGetter").GetGetMethod()).Emitter .ldc_i4_1 .ret() ; }