For when you have a gigabyte of JSON data to process:
public static class LazyJson { public static IEnumerable<T> DeserializeEnumerable<T>(Stream inputStream) where T: class, new() { var type = typeof(T); var properties = type.GetMembers(BindingFlags.Instance | BindingFlags.Public) .OfType<PropertyInfo>() .Where(pi => !pi.GetCustomAttributes(typeof(JsonIgnoreAttribute), true) .OfType<JsonIgnoreAttribute>().Any()) .ToDictionary(pi => { var jsonProperty = pi.GetCustomAttributes(typeof(JsonPropertyAttribute), true) .OfType<JsonPropertyAttribute>().FirstOrDefault(); return jsonProperty != null ? jsonProperty.PropertyName : pi.Name; }); using (var sr = new StreamReader(inputStream)) using (var jr = new JsonTextReader(sr)) { jr.DateParseHandling = DateParseHandling.DateTime; T currentObject = null; PropertyInfo currentProperty = null; while (jr.Read()) { switch (jr.TokenType) { case JsonToken.StartObject: currentObject = new T(); break; case JsonToken.PropertyName: currentProperty = properties[Convert.ToString(jr.Value)]; break; case JsonToken.String: currentProperty.SetValue(currentObject, Convert.ChangeType(jr.Value, currentProperty.PropertyType), null); break; case JsonToken.Integer: currentProperty.SetValue(currentObject, Convert.ChangeType(jr.Value, currentProperty.PropertyType), null); break; case JsonToken.Date: currentProperty.SetValue(currentObject, jr.Value, null); break; case JsonToken.EndObject: yield return currentObject; break; } } } } } |
Amazing how much neat stuff they’ve added to that language in 1 decade.