【发布时间】:2017-03-11 02:20:20
【问题描述】:
我有一个递归类(树层次结构),它派生自一个列表,它具有子项及其本身,由 JSON.NET 中的反序列化填充。
TLDR 版本是我想在子类中填充一个变量,从父类,在它存在的这个类的每个级别上,而不使用来自 JSON.NET 的 $ref 变量(存储到 cookie 时节省空间) .
对于那些关注我昨天的问题的人来说,这可能看起来像是重复的,但事实并非如此。这是相同的代码,但老问题围绕着 JSON 中的 setter 没有被触发(已解决),而答案带来了这个问题(措辞更贴切)。
最初的调用是:
_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;
}
所以问题在于我们已经确定反序列化不会从 List 调用标准的 Add/Insert 方法来填充列表。我们知道它是通过反射创建列表,但是如何创建呢?我可以在插入时拦截子类对父类的分配,以从父类中为其分配子类中的变量(即child.Parent = this)?
我尝试在 JSON.NET 源代码中四处寻找用于填充的集合中的方法(因为即使使用反射,它也必须通过调用方法调用来添加它们,对吗?)。除非...它正在做这样的事情:
CartItems items = new CartItems() { new GenericItem() { }, new GenericItem() { } };
编辑:CartItems 是从列表派生的类。它填充了多个 CartItem 实例。
【问题讨论】: