@@ -4444,13 +4444,15 @@ private static void GenerateTypeSetValueFor(TypeBuilder typeBuilder, Type type,
44444444 // il.Emit(OpCodes.Pop);
44454445 // }
44464446 //} else il.Emit(OpCodes.Stfld, field);
4447- } else {
4447+ } else
4448+ {
44484449 var propValue = il . DeclareLocal ( originPropType ) ;
44494450 var isValueType = propType . GetTypeInfo ( ) . IsValueType ;
44504451 var isPrimitiveType = propType . IsPrimitiveType ( ) ;
44514452 var isStruct = isValueType && ! isPrimitiveType ;
44524453 var isBool = propType == _boolType ;
44534454 var propNullLabel = ! isNullable && ! isBool ? il . DefineLabel ( ) : default ( Label ) ;
4455+ var skipDefaultFalseLabel = ! isNullable && ! isBool ? il . DefineLabel ( ) : default ( Label ) ;
44544456 var hasPropLabel = propNullLabel != default ( Label ) ;
44554457 var nullablePropValue = isNullable ? il . DeclareLocal ( originPropType ) : null ;
44564458 var equalityMethod = propType . GetMethod ( "op_Equality" ) ;
@@ -4463,24 +4465,35 @@ private static void GenerateTypeSetValueFor(TypeBuilder typeBuilder, Type type,
44634465
44644466 il . Emit ( OpCodes . Stloc , propValue ) ;
44654467
4466- if ( hasPropLabel ) {
4468+ if ( hasPropLabel )
4469+ {
44674470 if ( isStruct )
44684471 il . Emit ( OpCodes . Ldloca , propValue ) ;
44694472 else
44704473 il . Emit ( OpCodes . Ldloc , propValue ) ;
44714474
4472- if ( isValueType && isPrimitiveType ) {
4475+ if ( isValueType && isPrimitiveType )
4476+ {
44734477 LoadDefaultValueByType ( il , propType ) ;
4474- } else {
4478+ }
4479+ else
4480+ {
44754481 if ( ! isValueType )
44764482 il . Emit ( OpCodes . Ldnull ) ;
44774483 }
44784484
4479- if ( equalityMethod != null ) {
4485+ if ( equalityMethod != null )
4486+ {
44804487 il . Emit ( OpCodes . Call , equalityMethod ) ;
44814488 il . Emit ( OpCodes . Brtrue , propNullLabel ) ;
4482- } else {
4483- if ( isStruct ) {
4489+ il . Emit ( OpCodes . Ldarg , 4 ) ;
4490+ il . Emit ( OpCodes . Callvirt , _settingsSkipDefaultValue ) ;
4491+ il . Emit ( OpCodes . Brfalse , propNullLabel ) ;
4492+ }
4493+ else
4494+ {
4495+ if ( isStruct )
4496+ {
44844497
44854498 var tempValue = il . DeclareLocal ( propType ) ;
44864499
@@ -4493,57 +4506,37 @@ private static void GenerateTypeSetValueFor(TypeBuilder typeBuilder, Type type,
44934506 il . Emit ( OpCodes . Callvirt , _objectEquals ) ;
44944507
44954508 il . Emit ( OpCodes . Brtrue , propNullLabel ) ;
4496-
4497- } else
4498- il . Emit ( OpCodes . Beq , propNullLabel ) ;
4499- }
4500- }
4501-
4502- il . Emit ( OpCodes . Ldarg_2 ) ;
4503- il . Emit ( OpCodes . Ldloc , propValue ) ;
4504- //if (isNullable) {
4505- // il.Emit(OpCodes.Newobj, _nullableType.MakeGenericType(propType).GetConstructor(new[] { propType }));
4506- //}
4507-
4508- if ( isProp ) {
4509- if ( setter != null ) {
4510- if ( ! setter . IsPublic ) {
4511- if ( propType . GetTypeInfo ( ) . IsValueType )
4512- il . Emit ( OpCodes . Box , isNullable ? prop . PropertyType : propType ) ;
4513- il . Emit ( OpCodes . Ldtoken , setter ) ;
4514- il . Emit ( OpCodes . Call , _methodGetMethodFromHandle ) ;
4515- il . Emit ( OpCodes . Call , _setterPropertyValueMethod . MakeGenericMethod ( type ) ) ;
4516- } else
4517- il . Emit ( isTypeValueType ? OpCodes . Call : OpCodes . Callvirt , setter ) ;
4518- } else {
4519- var setField = type . GetField ( $ "<{ propName } >k__BackingField", BindingFlags . NonPublic | BindingFlags . Instance ) ;
4520- if ( setField == null )
4521- {
4522- //TODO: Use IL body and field token from prop.GetGetMethod().GetMethodBody()
4523- setField = fields . FirstOrDefault ( x => x . Name . EndsWith ( propName , StringComparison . OrdinalIgnoreCase ) ) ;
4524- }
4525-
4526- if ( setField != null )
4527- {
4528- if ( propType . GetTypeInfo ( ) . IsValueType )
4529- il . Emit ( OpCodes . Box , propType ) ;
4530- il . Emit ( OpCodes . Ldtoken , setField ) ;
4531- il . Emit ( OpCodes . Call , _methodGetFieldFromHandle ) ;
4532- il . Emit ( OpCodes . Call , _setterFieldValueMethod . MakeGenericMethod ( type ) ) ;
4509+ il . Emit ( OpCodes . Ldarg , 4 ) ;
4510+ il . Emit ( OpCodes . Callvirt , _settingsSkipDefaultValue ) ;
4511+ il . Emit ( OpCodes . Brfalse , propNullLabel ) ;
45334512 }
45344513 else
45354514 {
4536- il . Emit ( OpCodes . Pop ) ;
4537- il . Emit ( OpCodes . Pop ) ;
4515+ il . Emit ( OpCodes . Beq , propNullLabel ) ;
4516+ il . Emit ( OpCodes . Ldarg , 4 ) ;
4517+ il . Emit ( OpCodes . Callvirt , _settingsSkipDefaultValue ) ;
4518+ il . Emit ( OpCodes . Brfalse , propNullLabel ) ;
45384519 }
45394520 }
4521+ }
45404522
4541- } else il . Emit ( OpCodes . Stfld , field ) ;
4542-
4543- il . Emit ( OpCodes . Ret ) ;
4523+ SetClassMemberValue ( type , isTypeValueType , il , fields , prop , field , setter , isProp , propName , propType , isNullable , propValue ) ;
45444524
45454525 if ( hasPropLabel )
4526+ {
45464527 il . MarkLabel ( propNullLabel ) ;
4528+ }
4529+
4530+ if ( hasPropLabel )
4531+ {
4532+ il . Emit ( OpCodes . Ldarg , 4 ) ;
4533+ il . Emit ( OpCodes . Callvirt , _settingsSkipDefaultValue ) ;
4534+ il . Emit ( OpCodes . Brtrue , skipDefaultFalseLabel ) ;
4535+
4536+ SetClassMemberValue ( type , isTypeValueType , il , fields , prop , field , setter , isProp , propName , propType , isNullable , propValue ) ;
4537+
4538+ il . MarkLabel ( skipDefaultFalseLabel ) ;
4539+ }
45474540 }
45484541
45494542 il . Emit ( OpCodes . Ret ) ;
@@ -4557,6 +4550,56 @@ private static void GenerateTypeSetValueFor(TypeBuilder typeBuilder, Type type,
45574550 il . Emit ( OpCodes . Call , _skipProperty ) ;
45584551 }
45594552
4553+ private static void SetClassMemberValue ( Type type , bool isTypeValueType , ILGenerator il , FieldInfo [ ] fields , PropertyInfo prop , FieldInfo field , MethodInfo setter , bool isProp , string propName , Type propType , bool isNullable , LocalBuilder propValue )
4554+ {
4555+ il . Emit ( OpCodes . Ldarg_2 ) ;
4556+ il . Emit ( OpCodes . Ldloc , propValue ) ;
4557+
4558+ if ( isProp )
4559+ {
4560+ if ( setter != null )
4561+ {
4562+ if ( ! setter . IsPublic )
4563+ {
4564+ if ( propType . GetTypeInfo ( ) . IsValueType )
4565+ il . Emit ( OpCodes . Box , isNullable ? prop . PropertyType : propType ) ;
4566+ il . Emit ( OpCodes . Ldtoken , setter ) ;
4567+ il . Emit ( OpCodes . Call , _methodGetMethodFromHandle ) ;
4568+ il . Emit ( OpCodes . Call , _setterPropertyValueMethod . MakeGenericMethod ( type ) ) ;
4569+ }
4570+ else
4571+ il . Emit ( isTypeValueType ? OpCodes . Call : OpCodes . Callvirt , setter ) ;
4572+ }
4573+ else
4574+ {
4575+ var setField = type . GetField ( $ "<{ propName } >k__BackingField", BindingFlags . NonPublic | BindingFlags . Instance ) ;
4576+ if ( setField == null )
4577+ {
4578+ //TODO: Use IL body and field token from prop.GetGetMethod().GetMethodBody()
4579+ setField = fields . FirstOrDefault ( x => x . Name . EndsWith ( propName , StringComparison . OrdinalIgnoreCase ) ) ;
4580+ }
4581+
4582+ if ( setField != null )
4583+ {
4584+ if ( propType . GetTypeInfo ( ) . IsValueType )
4585+ il . Emit ( OpCodes . Box , propType ) ;
4586+ il . Emit ( OpCodes . Ldtoken , setField ) ;
4587+ il . Emit ( OpCodes . Call , _methodGetFieldFromHandle ) ;
4588+ il . Emit ( OpCodes . Call , _setterFieldValueMethod . MakeGenericMethod ( type ) ) ;
4589+ }
4590+ else
4591+ {
4592+ il . Emit ( OpCodes . Pop ) ;
4593+ il . Emit ( OpCodes . Pop ) ;
4594+ }
4595+ }
4596+
4597+ }
4598+ else il . Emit ( OpCodes . Stfld , field ) ;
4599+
4600+ il . Emit ( OpCodes . Ret ) ;
4601+ }
4602+
45604603 private static MethodInfo GenerateCreateListFor ( TypeBuilder typeBuilder , Type type ) {
45614604 MethodInfo method ;
45624605 var key = string . Concat ( type . FullName , typeBuilder == null ? Dynamic : string . Empty ) ;
0 commit comments