using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
public class AutomaticJsonNameTable : DefaultJsonNameTable
public AutomaticJsonNameTable(int maxToAdd)
this.maxToAutoAdd = maxToAdd;
public override string Get(char[] key, int start, int length)
var s = base.Get(key, start, length);
if (s == null && nAutoAdded < maxToAutoAdd)
s = new string(key, start, length);
public static class JsonSerializerExtensions
public static T DeserializeWithDefaultNameTable<T>(this JsonSerializer serializer, JsonReader reader)
JsonNameTable old = null;
var textReader = reader as JsonTextReader;
old = textReader.PropertyNameTable;
textReader.PropertyNameTable = null;
return serializer.Deserialize<T>(reader);
textReader.PropertyNameTable = old;
const int MaxPropertyNamesToCache = 200;
public static void Test()
Test(ObjectReferenceEqualityComparer<string>.Default, new AutomaticJsonNameTable(MaxPropertyNamesToCache));
Test(ObjectReferenceEqualityComparer<string>.Default, null);
Console.WriteLine("\nDone.");
public static void Test(IEqualityComparer<string> comparer, JsonNameTable nameTable)
var settings = new JsonSerializerSettings
var properties = new HashSet<string>(comparer);
using (var sr = new MockedStreamReader())
using (var jtr = new JsonTextReader(sr) { PropertyNameTable = nameTable })
if (jtr.TokenType == JsonToken.PropertyName)
properties.Add((string)jtr.Value);
Console.WriteLine("using {0} for a name table, {1} properties were allocated.", (object)nameTable ?? "null", properties.Count);
public class MockedStreamReader : StreamReader
private bool initialProvided = false;
private byte[] initialBytes = Encoding.Default.GetBytes("[");
private static readonly byte[] recordBytes;
static MockedStreamReader()
var recordSb = new StringBuilder("{");
Enumerable.Range(0, 50).ToList().ForEach(i =>
recordSb.Append(string.Format("\"Key{0}\": \"Value{0}\"", i));
recordBytes = Encoding.Default.GetBytes(recordSb.ToString());
public MockedStreamReader()
: base(new MemoryStream())
public override int Read(char[] buffer, int index, int count)
if (this.initialProvided)
var length = Math.Min(recordBytes.Length - start, count);
var end = start + length;
nextStart = end >= recordBytes.Length ? 0 : end;
Array.Copy(recordBytes, start, buffer, index, length);
Array.Copy(initialBytes, buffer, initialBytes.Length);
return initialBytes.Length;
public class ObjectReferenceEqualityComparer<T> : EqualityComparer<T>
private static IEqualityComparer<T> _defaultComparer;
public new static IEqualityComparer<T> Default
get { return _defaultComparer ?? (_defaultComparer = new ObjectReferenceEqualityComparer<T>()); }
#region IEqualityComparer<T> Members
public override bool Equals(T x, T y)
return ReferenceEquals(x, y);
public override int GetHashCode(T obj)
return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(obj);
public class JsonArrayPool : IArrayPool<char>
public static readonly JsonArrayPool Instance = new JsonArrayPool();
public char[] Rent(int minimumLength)
return ArrayPool<char>.Shared.Rent(minimumLength);
public void Return(char[] array)
ArrayPool<char>.Shared.Return(array);
public static void Main()
Console.WriteLine("Environment version: " + Environment.Version);
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");