必要なことは、カスタム コンバーターを作成し、継承を使用することです。
まず、2 つのサブクラスがあるように変更しました。
public class JsonTestObject
{
}
public class JsonTestResultValue : JsonTestObject
{
public int b;
public int c;
}
public class JsonTestResultArray : JsonTestObject
{
public JArray Array { get; set; }
public JsonTestResultArray(JArray array)
{
Array = array;
}
}
メイン構造で使用されるもの:
public class JsonTest
{
public JsonTestResult[] result;
}
public class JsonTestResult
{
public JsonTestObject a;
}
次に、どのサブクラスを使用するかを識別できるようにする必要があります。そのために、開始トークンがオブジェクト用か配列用かを確認できます。それは内部で行われますJsonConverter
:
public class JsonTestConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(JsonTestObject).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader,
Type objectType, object existingValue, JsonSerializer serializer)
{
//Is it an array?
var token = reader.TokenType;
if (token == JsonToken.StartArray)
{
var array = JArray.Load(reader);
return new JsonTestResultArray(array);
}
var item = JObject.Load(reader);
return item.ToObject<JsonTestResultValue>();
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer,
object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
最後に、逆シリアル化するときにコンバーターを指定する必要があります。
class Program
{
static void Main(string[] args)
{
var str = @"{
""result"":
[
{""a"":{""b"":1,""c"":2}},
{""a"":{""b"":1,""c"":2}},
{""a"":{""b"":1,""c"":2}},
{""a"":[]}
]
}";
var deserializedObject = JsonConvert.DeserializeObject<JsonTest>(str, new JsonTestConverter());
}
}
おそらく、JArray を実際の配列型に対して変更したいと思うでしょうJsonTestResultArray
。