public void GenerateLoad(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx, Action <IILGen> pushDescriptor, Type targetType) { if (targetType == typeof(object)) { var resultLoc = ilGenerator.DeclareLocal(typeof(DynamicObject), "result"); var labelNoCtx = ilGenerator.DefineLabel(); ilGenerator .Do(pushDescriptor) .Castclass(typeof(ObjectTypeDescriptor)) .Newobj(typeof(DynamicObject).GetConstructor(new[] { typeof(ObjectTypeDescriptor) }) !) .Stloc(resultLoc) .Do(pushCtx) .BrfalseS(labelNoCtx) .Do(pushCtx) .Ldloc(resultLoc) .Callvirt(() => default(ITypeBinaryDeserializerContext).AddBackRef(null)) .Mark(labelNoCtx); var idx = 0; foreach (var pair in _fields) { var idxForCapture = idx; ilGenerator.Ldloc(resultLoc); ilGenerator.LdcI4(idx); pair.Value.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor) .LdcI4(idxForCapture) .Callvirt(() => default(ITypeDescriptor).NestedType(0)), typeof(object), _typeSerializers.ConvertorGenerator); ilGenerator.Callvirt(() => default(DynamicObject).SetFieldByIdxFast(0, null)); idx++; } ilGenerator .Ldloc(resultLoc) .Castclass(typeof(object)); } else { var resultLoc = ilGenerator.DeclareLocal(targetType, "result"); var labelNoCtx = ilGenerator.DefineLabel(); var defaultConstructor = targetType.GetConstructor(Type.EmptyTypes); if (defaultConstructor == null) { ilGenerator .Ldtoken(targetType) .Call(() => Type.GetTypeFromHandle(new RuntimeTypeHandle())) .Call(() => RuntimeHelpers.GetUninitializedObject(null)) .Castclass(targetType); } else { ilGenerator .Newobj(defaultConstructor); } ilGenerator .Stloc(resultLoc) .Do(pushCtx) .BrfalseS(labelNoCtx) .Do(pushCtx) .Ldloc(resultLoc) .Callvirt(() => default(ITypeBinaryDeserializerContext).AddBackRef(null)) .Mark(labelNoCtx); var props = targetType.GetProperties(BindingFlags.Instance | BindingFlags.Public); for (var idx = 0; idx < _fields.Count; idx++) { var idxForCapture = idx; var pair = _fields[idx]; var prop = props.FirstOrDefault(p => GetPersistentName(p) == pair.Key); if (prop == null || !_typeSerializers.IsSafeToLoad(prop.PropertyType)) { pair.Value.GenerateSkipEx(ilGenerator, pushReader, pushCtx); continue; } ilGenerator.Ldloc(resultLoc); pair.Value.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(idxForCapture) .Callvirt(() => default(ITypeDescriptor).NestedType(0)), prop.PropertyType, _typeSerializers.ConvertorGenerator); ilGenerator.Callvirt(prop.GetAnySetMethod() !); } ilGenerator.Ldloc(resultLoc); } }