private static Func <DeserializationContext, object> ForCollection(Type type, Func <Type, TypeDescriptor> descriptorSource) { var element = ReflectionUtils.FindCollectionElementType(type); var constructor = ReflectionUtils.BuildConstructor(typeof(List <>).MakeGenericType(element)); var elementDescriptor = descriptorSource(element); return(context => { var reader = context.Reader; var bufferPart = new BufferPart(); var token = reader.Read(ref bufferPart, out var _); if (token == JsonToken.Null) { return null; } var target = (IList)constructor(); if (token != JsonToken.ArrayStart) { throw Exceptions.BadToken(reader, token, JsonToken.ObjectStart); } var finalizer = type.IsArray ? new Func <IList, object>(i => { var array = Array.CreateInstance(element, i.Count); i.CopyTo(array, 0); return array; }) : null; var isFirst = true; while (true) { if (reader.PeekToken() == JsonToken.ArrayEnd) { reader.Read(ref bufferPart, out var _); return finalizer != null?finalizer(target) : target; } if (!isFirst) { token = reader.Read(ref bufferPart, out var _); if (token != JsonToken.ValueSeparator) { throw Exceptions.BadToken(reader, token, JsonToken.ValueSeparator); } } var item = elementDescriptor.Reader(context); target.Add(item); isFirst = false; } }); }
private static Action <object, SerializationContext> ForCollection(Type root, Func <Type, TypeDescriptor> descriptorSource) { var elementType = ReflectionUtils.FindCollectionElementType(root); var descriptor = descriptorSource(elementType); return((obj, context) => { var writer = context.Writer; if (obj == null) { writer.WriteNull(); return; } writer.BeginArray(); context.Depth--; foreach (var item in (IEnumerable)obj) { writer.ArrayItem(); descriptor.Writer(item, context); } context.Depth++; writer.EndArray(); }); }