2015-11-19 34 views
3

由於缺乏真正的預見性,我已經使用NetDataContractSerializer序列化了一大批僅使用Serializable修飾的數據,現在我想添加一個新字段。我有什麼選擇?NetDataContractSerializer使用新屬性進行反序列化

原始類看起來是這樣的(具有繼承幾級的,不少領域):

[Serializable] 
public class InheritedClass : BaseClass 
{ 
    public string StringId { get; set; } 
} 

現在我想補充另一個屬性,這樣說:

[Serializable] 
public class InheritedClass : BaseClass 
{ 
    public string StringId { get; set; } 
    public int IntId { get; set; } 
} 

現在,當我更新的類和去反序列化,我收到一個異常,因爲新的字段不存在,是這樣的:

Exception thrown: 'System.Runtime.Serialization.SerializationException' in System.Runtime.Serialization.dll 

Additional information: Error in line 1 position 601. 'Element' '_x003C_StringId_x003E_k__BackingField' from namespace 'http://schemas.datacontract.org/2004/07/QT' is not expected. Expecting element '_x003C_IntId_x003E_k__BackingField'. 

好吧,所以這是有道理的,因爲NetDataContractSerializer需要相同的類。我能得到周圍使用數據成員的屬性,如:

[DataMember(IsRequired = false)] 

那麼問題是,切換到數據成員(如我應該做的前期,或使用不同的串行)改變隱含的字母順序,然後大部分的衆所周知,我的領域將默默不反序列化。

我試圖添加一個與磁盤上的順序手動(通過屬性上的Order屬性)內聯的順序,但這似乎也沒有被遵守。 (我沒有看到我可以在原始xml中匹配的訂單值。)

是否有任何其他選項可以加載xml並插入缺少的節點? (或者等價地設置一個並行類型並反序列化一個重新序列化到另一個?)如果不是,我可能會加載當前類型並反序列化爲JsonNet或protobuf,但是我錯過了更直接的DataMember /等等?

回答

1

[Serializable]標記類型意味着該類型應該通過序列化其公有和專用字段而不是其屬性。當添加一個新字段時,通常用來處理遺留數據的東西是用[OptionalField]來標記它,以指示它不總是出現在串行化流中 - 但是一個不能用做到這一點,因爲它具有自動實現的屬性,因爲一個不能訪問祕密支持領域。

解決的辦法是明確地實施所有新特性,並標記與所需的屬性支持字段:

[Serializable] 
public class InheritedClass : BaseClass 
{ 
    public string StringId { get; set; } 

    [OptionalField] 
    int intId; 

    public int IntId { get { return intId; } set { intId = value; } } 
}  
相關問題