而不是定義這是一個序列化問題(如何序列化和反序列化對父代的反向引用),將其定義爲類設計問題可能是有意義的,即
由於家長和孩子的層次結構,如何保證孩子的父母背引用自動將其添加到他們的父母時設置是否正確?
一旦以這種方式定義問題並解決問題,在反序列化和程序化數據創建期間應保證正確性,因爲父反向引用永遠不需要序列化或反序列化。
完成此操作的一種方法是定義一個自定義子類Collection<T>
,該子類自動設置並清除父回引用。
首先,定義以下接口和收集:
public interface IHasParent<TParent> where TParent : class
{
TParent Parent { get; }
void OnParentChanging(TParent newParent);
}
public class ChildCollection<TParent, TChild> : Collection<TChild>
where TChild : IHasParent<TParent>
where TParent : class
{
readonly TParent parent;
public ChildCollection(TParent parent)
{
this.parent = parent;
}
protected override void ClearItems()
{
foreach (var item in this)
{
if (item != null)
item.OnParentChanging(null);
}
base.ClearItems();
}
protected override void InsertItem(int index, TChild item)
{
if (item != null)
item.OnParentChanging(parent);
base.InsertItem(index, item);
}
protected override void RemoveItem(int index)
{
var item = this[index];
if (item != null)
item.OnParentChanging(null);
base.RemoveItem(index);
}
protected override void SetItem(int index, TChild item)
{
var oldItem = this[index];
if (oldItem != null)
oldItem.OnParentChanging(null);
if (item != null)
item.OnParentChanging(parent);
base.SetItem(index, item);
}
}
然後定義您的MyObject
和RootObject
類型如下:
public class MyObject : IHasParent<MyObject>
{
readonly ChildCollection<MyObject, MyObject> childObjects;
public MyObject() { this.childObjects = new ChildCollection<MyObject, MyObject>(this); }
public string Name { get; set; }
public IList<MyObject> ChildObjects { get { return childObjects; } }
#region IHasParent<MyObject> Members
[JsonIgnore]
public MyObject Parent { get; private set; }
public void OnParentChanging(MyObject newParent)
{
Parent = newParent;
}
#endregion
// Added to suppress serialization of empty ChildObjects collections to JSON.
public bool ShouldSerializeChildObjects() { return childObjects.Count > 0; }
}
public class RootObject
{
public RootObject() { this.Object = new List<MyObject>(); }
public List<MyObject> Object { get; set; }
}
注:
收集IList<MyObject> ChildObjects
在MyObject
是啓動LY。 Json.NET(和XmlSerializer
就此而言)可以成功反序列化一個只能獲得預分配的集合。
方法ShouldSerializeChildObjects()
是可選的,並防止對空的ChildObjects []
數組值進行序列化。
由於ObservableCollection<T>
本身就是Collection<T>
一個子類,你可以選擇它作爲基類爲ChildCollection<TParent, TChild>
,如果你需要通知項目時添加或刪除。
Parent
屬性標有[JsonIgnore]
以防止其序列化。
樣本fiddle包括一些基本的單元測試。
來源
2017-10-19 19:52:40
dbc
您是否嘗試將['PreserveReferencesHandling'](https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_PreserveReferencesHandling.htm)設置設置爲'Objects'?如果你這樣做,你不應該需要一個轉換器;引用將通過特殊的'$ id'和'$ ref'元屬性保存在JSON中。 –
@BrianRogers,我想過爲「Object Class」添加一個「Parent Object」屬性。這樣我就可以得到父母的參考。這個參考資料是否適合這種用途? (如果它可以作爲JSON文件上父節點的引用) –
是的,您的子對象可以引用父對象,反之亦然,如果您在序列化和反序列化時都使用該設置,它應該可以工作。 –