簡體   English   中英

單聲道是否通過帶有saveObjectReferences標志支持DataContractSerializer?

[英]Does mono support DataContractSerializer with the preserveObjectReferences flag?

我正在嘗試使用c#mono(mono v2.6)序列化復雜的圖形,該圖形具有雙向鏈接,並且存在創建循環依賴項的對象。 經過一番閱讀后,我嘗試設置prepareObjectReferences標志,該標志應允許設置循環引用(此構造函數):

public DataContractSerializer(
 Type type,
 IEnumerable<Type> knownTypes,
 int maxItemsInObjectGraph,
 bool ignoreExtensionDataObject,
 bool preserveObjectReferences,
 IDataContractSurrogate dataContractSurrogate
)

我得到的異常如下:

SerializationException: Circular reference of an object in the object graph was found: 'ShaderMasterNode' of type ShaderMasterNode

有沒有人幸運地在mono中序列化復雜對象? 根據此處的文檔: http : //go-mono.com/status/status.aspx?reference=3.5&profile=2.0&assembly=System.Runtime.Serialization支持這些構造函數。

編輯:據我所知,您還需要在DataContractAttribute中設置IsReference = true屬性,請參見此處此處

IsReference獲取或設置一個值,該值指示是否保留對象參考數據。 PreserveObjectReferences應該獲得一個值,該值指定是否使用非標准XML構造來保留對象引用數據。

Mono確實支持數據合同序列化,但是正如在源代碼中的注釋所表明的那樣,還有一些工作要做:

([[MonoTODO(“支持數組;支持可序列化;支持SharedType;使用DataContractSurrogate”)]-prepareObjectReferences指示輸出是否應包含ms:Id。)

嘗試在此處閱讀.NET Framework的數據合同序列化文檔,並將其與Mono中可用的源代碼進行比較,這將使事情變得清晰。

也對其他System.Runtime.Serialization命名空間執行相同的操作,從MSDN中閱讀文檔,並與在Mono命名空間中獲得的內容進行比較

Mono中System.Runtime.Serialization命名空間的源代碼在此處可用,DataContractSerializer類源在此處包含以下有趣的內容:

// Three constructors with this property

    public DataContractSerializer (Type type,
   IEnumerable<Type> knownTypes,
   int maxObjectsInGraph,
   bool ignoreExtensionDataObject,
   **bool preserveObjectReferences,**
   IDataContractSurrogate dataContractSurrogate)
   : this (type, knownTypes)
  {
   Initialize (maxObjectsInGraph,
    ignoreExtensionDataObject,
    **preserveObjectReferences,**
    dataContractSurrogate);
  }

  public DataContractSerializer (Type type,
   string rootName,
   string rootNamespace,
   IEnumerable<Type> knownTypes,
   int maxObjectsInGraph,
   bool ignoreExtensionDataObject,
   **bool preserveObjectReferences,**
   IDataContractSurrogate dataContractSurrogate)
   : this (type, rootName, rootNamespace, knownTypes)
  {
   Initialize (maxObjectsInGraph,
    ignoreExtensionDataObject,
    **preserveObjectReferences,**
    dataContractSurrogate);
  }

  public DataContractSerializer (Type type,
   XmlDictionaryString rootName,
   XmlDictionaryString rootNamespace,
   IEnumerable<Type> knownTypes,
   int maxObjectsInGraph,
   bool ignoreExtensionDataObject,
   **bool preserveObjectReferences,**
   IDataContractSurrogate dataContractSurrogate)
   : this (type, rootName, rootNamespace, knownTypes)
  {
   Initialize (maxObjectsInGraph,
    ignoreExtensionDataObject,
    **preserveObjectReferences,**
    dataContractSurrogate);
  }

// Initialize()方法

    void Initialize (
   int maxObjectsInGraph,
   bool ignoreExtensionDataObject,
   bool preserveObjectReferences,
   IDataContractSurrogate dataContractSurrogate)
  {
   if (maxObjectsInGraph < 0)
    throw new ArgumentOutOfRangeException ("maxObjectsInGraph must not be negative.");
   max_items = maxObjectsInGraph;
   ignore_ext = ignoreExtensionDataObject;
   preserve_refs = preserveObjectReferences;
   surrogate = dataContractSurrogate;

   PopulateTypes (Type.EmptyTypes);
  }

// prepareObjectReferences()屬性

    public bool PreserveObjectReferences {
   get { return preserve_refs; }
  }

根據

**默認情況下,DataContractSerializer不會保留對象引用; 多次引用的對象的值被序列化多次。 如果對象是相互(循環)引用(例如,循環鏈表)的一部分,則在序列化期間會引發異常。

在構造DataContractSerializer **時,可以通過為參數PreserveObjectReference傳遞true來使DataContractSerializer保留對象引用:

new DataContractSerializer(type, name, ns, knownTypes,
            0x7FFF /*maxObjectsInGraph*/,
            false/*ignoreExtensionDataObject*/,
            true/*preserveObjectReferences*/,
            null/*dataContractSurrogate*/);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM