Я думаю, я понял - вы работаете в предположении, что ребенок может быть независимым объектом, а не только привязанным к родителю (только на который ссылается родитель). Понял.
я есть рекурсивный класс (древовидная иерархия), который происходит от списка, который имеет дочерние элементы и сам по себе, заполненный десериализацией в JSON.NET.
Версия TLDR заключается в том, что я хочу заполнить переменную в дочерних элементах от родителя на каждом уровне этого класса, где она существует, без использования переменных $ ref из JSON.NET (экономит место при сохранении в cookie).
Для тех, кто следовал за моим вчерашним вопросом, это может выглядеть как дубликат, но это не так. Это тот же код, но старый вопрос вращался вокруг того, что сеттеры в JSON не запускались (решались), и ответ вызвал этот вопрос (более метко сформулированный).
Первоначальный вызов будет:
_Items = Cookies.Instance.GetJObject<CartItems>(COOKIE, jsonSetting);
Какие звонки:
public T GetJObject<T>(string cookieName, JsonSerializerSettings jset = null)
{
string cookieContent = Get(cookieName);
return JsonConvert.DeserializeObject<T>(cookieContent, jset);
}
Пользовательский класс конвертера выглядит следующим образом:
public class JsonCartConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(CartItem).IsAssignableFrom(objectType);
}
public override bool CanWrite
{
get
{
return false;
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject obj = JObject.Load(reader);
var type = obj["t"] != null ? (CARTITEMTYPE)obj["t"].Value<int>() : CARTITEMTYPE.GENERIC;
var item = CartItems.NewByType(type);
serializer.Populate(obj.CreateReader(), item);
return item;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
}
}
Результирующий JSON выглядит следующим образом:
[{"t":1,"i":1,"n":4,"r":false,"c":[{"t":5,"i":2,"n":4,"r":false,"c":[]}]},{"t":1,"i":3,"n":4,"r":false,"c":[{"t":5,"i":4,"n":4,"r":false,"c":[{"t":4,"i":6,"n":14,"r":false,"c":[]}]},{"t":1,"i":5,"n":15,"r":false,"c":[]}]}]
И то, что я пытаюсь сделать, будет похоже на это:
public class CartItems : List<CartItem>{
public new CartItem Add(CartItem item)
{
item.Parent = this;
base.Add(item);
return item;
}
Таким образом, проблема в том, что мы установили, что десериализация не вызывает стандартные методы Add / Insert из List для заполнения списка. Мы знаем, что это создает список с помощью размышлений, но как? Могу ли я перехватить присваивание дочернего класса родительскому классу после вставки, чтобы присвоить ему переменную в дочернем классе из родительского класса (т.е. child.Parent = this)?
Я попытался покопаться в источнике JSON.NET, чтобы найти метод в коллекции, которую он использует для заполнения (потому что даже с отражением, он должен добавлять их, вызывая вызов метода, верно?). Если только ... Он делает что-то вроде этого:
CartItems items = new CartItems() { new GenericItem() { }, new GenericItem() { } };
Изменить: CartItems является классом, полученным из списка. Он заполнен несколькими экземплярами CartItem.