public void GenerateLoad(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx, Action <IILGen> pushDescriptor, Type targetType) { if (targetType == typeof(object)) { targetType = GetPreferedType(); } var localCount = ilGenerator.DeclareLocal(typeof(int)); var targetIList = targetType.GetInterface("IList`1") ?? targetType; var targetTypeArguments = targetIList.GetGenericArguments(); var itemType = _typeSerializers.LoadAsType(_itemDescriptor, targetTypeArguments[0]); if (targetType.IsArray) { var localArray = ilGenerator.DeclareLocal(targetType); var loadFinished = ilGenerator.DefineLabel(); var localIndex = ilGenerator.DeclareLocal(typeof(int)); var next = ilGenerator.DefineLabel(); ilGenerator .LdcI4(0) .Stloc(localIndex) .Do(pushReader) .Callvirt(() => default(AbstractBufferedReader).ReadVUInt32()) .ConvI4() .Dup() .Stloc(localCount) .Brfalse(loadFinished) .Ldloc(localCount) .LdcI4(1) .Sub() .Dup() .Stloc(localCount) .Newarr(itemType) .Stloc(localArray) .Mark(next) .Ldloc(localCount) .Ldloc(localIndex) .Sub() .Brfalse(loadFinished) .Ldloc(localArray) .Ldloc(localIndex); _itemDescriptor.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(0).Callvirt(() => default(ITypeDescriptor).NestedType(0)), itemType, _convertorGenerator); ilGenerator .Stelem(itemType) .Ldloc(localIndex) .LdcI4(1) .Add() .Stloc(localIndex) .Br(next) .Mark(loadFinished) .Ldloc(localArray) .Castclass(targetType); } else { var listType = typeof(ListWithDescriptor <>).MakeGenericType(itemType); if (!targetType.IsAssignableFrom(listType)) { throw new NotSupportedException(); } var localList = ilGenerator.DeclareLocal(listType); var loadFinished = ilGenerator.DefineLabel(); var next = ilGenerator.DefineLabel(); ilGenerator .Do(pushReader) .Callvirt(() => default(AbstractBufferedReader).ReadVUInt32()) .ConvI4() .Dup() .Stloc(localCount) .Brfalse(loadFinished) .Ldloc(localCount) .LdcI4(1) .Sub() .Dup() .Stloc(localCount) .Do(pushDescriptor) .Newobj(listType.GetConstructor(new[] { typeof(int), typeof(ITypeDescriptor) })) .Stloc(localList) .Mark(next) .Ldloc(localCount) .Brfalse(loadFinished) .Ldloc(localCount) .LdcI4(1) .Sub() .Stloc(localCount) .Ldloc(localList); _itemDescriptor.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(0).Callvirt(() => default(ITypeDescriptor).NestedType(0)), itemType, _convertorGenerator); ilGenerator .Callvirt(listType.GetInterface("ICollection`1").GetMethod("Add")) .Br(next) .Mark(loadFinished) .Ldloc(localList) .Castclass(targetType); } }