using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
public class InterfaceToConcreteConverter<TInterface, TConcrete> : JsonConverter where TConcrete : TInterface
static InterfaceToConcreteConverter()
if (typeof(TInterface) == typeof(TConcrete))
throw new InvalidOperationException(string.Format("typeof({0}) == typeof({1})", typeof(TInterface), typeof(TConcrete)));
public override bool CanConvert(Type objectType) =>objectType == typeof(TInterface);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) => serializer.Deserialize(reader, typeof(TConcrete));
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
public IB b { get; set; }
public IC c { get; set; }
public int v { get; set; }
public static class JsonExtensions
public static JsonSerializerSettings DefaultSettings { get; } =
new JsonSerializerSettings
Converters = { new InterfaceToConcreteConverter<IA, A>(),
new InterfaceToConcreteConverter<IB, B>(),
new InterfaceToConcreteConverter<IC, C>(),}
public static void Test()
var settings = new JsonSerializerSettings
Converters = { new InterfaceToConcreteConverter<IA, A>(),
new InterfaceToConcreteConverter<IB, B>(),
new InterfaceToConcreteConverter<IC, C>(),}
string aSer = JsonConvert.SerializeObject( a, settings );
A aDeser = JsonConvert.DeserializeObject<A>( aSer, JsonExtensions.DefaultSettings );
var json2 = JsonConvert.SerializeObject( aDeser, settings );
Assert.AreEqual(aSer, json2);
Console.WriteLine("Round-tripped JSON for {0}:", aDeser);
Console.WriteLine(json2);
Assert.Catch(() =>new InterfaceToConcreteConverter<IA, IA>());
Assert.Catch(() =>new InterfaceToConcreteConverter<IA, IA>());
new InterfaceToConcreteConverter<IA, IA>();
Console.WriteLine("Caught expected exception:\n {0}", ex);
public static void Main()
Console.WriteLine("Environment version: {0} ({1}), {2}", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version, Environment.OSVersion);
Console.WriteLine("{0} version: {1}", typeof(JsonSerializer).Namespace, typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");