我定義了基礎的樹結構,為了便于擴展,使用了泛型:
節點:
public class Node{
public string ID{get;set;}
public string Description{get;set;}
public IList<Node> Children;//------問題出在這里
}
樹物件:
public class Tree<T>:Node,where T:Node{
......樹物件的各種方法
}
實際使用時,比如選單如下定義:
protected Tree<MenuItem> menus;
序列化時正常:
{"Parent":null,"Children":[{"Parent":null,"Children":[{"Parent":null,"Children":null,"ID":"Menu","Description":"選單設定","Index":0,"IsValid":false},{"Parent":null,"Children":null,"ID":"Setup","Description":"系統配置","Index":0,"IsValid":false}],"ID":"Web","Description":"Web控制臺","Index":0,"IsValid":false}],"ID":null,"Description":null,"Index":0,"IsValid":false}
但是在反序列化時,由于節點的Children定義為IList<Node>
System.Text.Json反序列化實體時使用了Node物件,并非MenuItem物件。
請問該怎么定義Node類,才能在后續擴展中順利使用MenuItem呢?
uj5u.com熱心網友回復:
額。。。本來就不是一個型別的。那你自己轉換成Node后,在樹洞轉換為Tree<MenuItem>
uj5u.com熱心網友回復:
在反序列化時,子節點得到的物件就是Node,無法轉換為MenuItem目前的寫法:
public class MenuItem:Node
{
}
可以想到的解決辦法:
public class MenuItem:Node{
public new IList<MenuItem> Children;//------覆寫父類的Children,不過這顯然違背了繼承的思路,不如每個不同的類都單獨寫算了
}
uj5u.com熱心網友回復:
你直接這樣呢
var node = JsonConvert.DeserializeObject<MenuItem>(json);
uj5u.com熱心網友回復:
的確var node = JsonConvert.DeserializeObject<MenuItem>(json);
是可以序列化到指定的物件型別。但對于一個樹結構(MenuItem型別是從Node型別擴展而來),node的Children,子節點在此時由于定義為 IList<Node>,會被序列化為Node而不是MenuItem。除非被覆寫定義為:IList<MenuItem>。這樣一來,所有擴展Node的物件都要覆寫下Children屬性,失去了繼承的意義。
現在我嘗試用容器方式來做,還沒完成驗證(比如RPC傳輸是否有其他問題,實體化對應的資料庫結構問題)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/80483.html
標籤:C#
