Десериализация гетерогенного массива JSON в ковариантный List <> с использованием JSON.NET

У меня есть JSON-массив, содержащий объекты разных типов с разными свойствами. Одно из свойств называется «тип» и определяет тип элемента массива. Вот пример моих данных:

   [{
        type : "comment",
        text : "xxxx"
    }, {
        type : "code",
        tokens : [{
                type : "ref",
                data : "m"
            }, {
                type : "operator",
                data : "e"
            }
        ]
    }, {
        type : "for",
        boundLocal : {
            type : "local",
            name : "i",
            kind : "Number"
        },
        upperBound : {
            type : "ref",
            tokens : [{
                    type : "operator",
                    data : "3"
                }, {
                    type : "operator",
                    data : "0"
                }
            ]
        },
        body : [{
                type : "code",
                tokens : [{
                        type : "ref",
                        data : "x"
                    }
                ]
            }, {
                type : "code",
                tokens : [{
                        type : "ref",
                        data : "y"
                    }
                }
                ]
        ]
    ]

Чтобы сопоставить эти объекты с моей реализацией .Net, я определяю набор классов: один базовый класс и несколько дочерних классов (со сложной иерархией, имеющей 4 «поколения»). Вот лишь небольшой пример этих классов:

public abstract class TExpression
{
    [JsonProperty("type")]
    public string Type { get; set; }
}

public class TComment : TExpression
{
    [JsonProperty("text")]
    public string Text { get; set; }
}   

public class TTokenSequence : TExpression
{
    [JsonProperty("tokens")]
    public List<TToken> Tokens { get; set; }
}

Я хочу иметь возможность десериализовать этот массив в ковариантный общий список, объявленный как:

List<TExpression> myexpressions = JsonConvert.DeserializeObject<List<TExpression>>(aststring);

Этот список должен содержать экземпляры соответствующих дочерних классов, унаследованных от TExpression, поэтому я могу использовать следующий код позже в моем коде:

foreach(TExpression t in myexpressions)
{
    if (t is TComment) dosomething;
    if (t is TTokenSequence) dosomethingelse;
}

Как я могу достичь его с помощью JSON.NET?

39
задан Alexander Galkin 23 November 2011 в 11:46
поделиться