カスタムを使用してConverter
、そのインターフェースのタイプを逆シリアル化する方法をJSON.NETに指示できます。以下のコードは例を示しています。
public class StackOverflow_12197892
{
public class Data
{
public IEnumerable<IChild> Children { get; set; }
public override string ToString()
{
return string.Format("Data{{Children=[{0}]}}",
string.Join(", ", Children.Select(c => string.Format("{0}/{1}", c.Name, c.IsFemale ? "girl" : "boy"))));
}
}
public interface IChild
{
string Name { get; }
bool IsFemale { get; }
}
public class Son : IChild
{
public Son(string name)
{
this.Name = name;
}
public string Name { get; private set; }
public bool IsFemale { get { return false; } }
}
public class Daughter : IChild
{
public Daughter(string name)
{
this.Name = name;
}
public string Name { get; private set; }
public bool IsFemale { get { return true; } }
}
class ChildConverter : Newtonsoft.Json.JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(IChild).IsAssignableFrom(objectType);
}
public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
{
JObject obj = serializer.Deserialize<JToken>(reader) as JObject;
if (obj != null)
{
bool isFemale = obj["isFemale"].ToObject<bool>();
string name = obj["name"].ToObject<string>();
if (isFemale)
{
return new Daughter(name);
}
else
{
return new Son(name);
}
}
else
{
return null;
}
}
public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
public static void Test()
{
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
serializer.Converters.Add(new ChildConverter());
string json = "{'Children':[{'name':'John',isFemale:false},{'name':'Mary',isFemale:true}]}".Replace('\'', '\"');
var obj = serializer.Deserialize(new StringReader(json), typeof(Data));
Console.WriteLine(obj);
}
}