2012-05-22 30 views
8

我正在使用XMLSerializer將此類保存到文件中。該類有一個字符串和一個枚舉,如下所示:XmlSerializer:如何反序列化不再存在的枚舉值

public class IOPoint 
{ 
    string Name {get; set;} 
    TypeEnum {get; set;} 
} 


public enum TypeEnum 
{ 
    Temperature, 
    Pressure, 
    Humidity, 
} 

當序列化它看起來像這樣。

<IOPoint> 
    <Name>Relative Humidity</Name> 
    <TypeEnum>Humidity</TypeEnum> 
</IOPoint> 

我一直在序列化和反序列化這個對象,幾個版本沒有問題。我不再需要支持溼度,所以我將它從枚舉中移除。但是,從XML反序列化時,這會導致異常,因爲TypeEnum字段中的值Humidity對於TypeEnum而言不是有效值。這是有道理的,但如何處理呢?

我想要做的就是忽略這個錯誤。並將值保留爲空。我試過實現OnUnknownElement XmlDeserilizationEvent類。不幸的是,這並沒有發現這個錯誤。

關於如何捕獲和忽略這個錯誤的任何想法(我可以在反序列化完成後清理)。

米奇

+0

如果您找到了我很想知道的解決方案。我有一個相關的問題,服務器端包含一個客戶端不知道的新枚舉標誌值,所以真的想找到一種方法來管理這個字段的序列化。下次我只使用一個int,但現在...向後兼容。 – avenmore

回答

5

您可以標記過時

public enum TypeEnum 
{ 
    Temperature, 
    Pressure, 
    [Obsolete] 
    Humidity 
} 
+2

我無法使用[Obsolete]屬性的原因是因爲在我們的代碼中迭代枚舉值是很常見的做法。所以即使「溼度」被標記爲過時,它仍然會在我們的foreach循環中找到。 (除非有重寫枚舉器的方法嗎?) – Mitch

+0

無論你在哪裏使用它,你都可以使變量爲null嗎? 例如,TypeEnum?val = null; – 2016-09-16 19:46:11

4

它通常被認爲是不好的做法,刪除一個枚舉成員後您的圖書館已在使用中的成員。爲什麼不保留該成員,但將其標記爲[Obsolete]屬性以防止將來使用?指定ObsoleteAttribute(string,bool)構造函數的第二個參數爲true將導致編譯時錯誤(如果標記的成員被訪問)。

public enum TypeEnum 
{ 
    Temperature, 
    Pressure, 

    [Obsolete("It's always sunny in Philadelphia", true)] 
    Humidity, 
} 

爲了規避檢查反序列化值時,你可以比較反對潛在價值的錯誤:typeEnum == (TypeEnum)2

1

您可以實施IXmlSerializable,您可以在其中使用TryParse作爲枚舉。

但我同意使用Obsolete屬性的其他海報。

+0

如果我找不到另一種解決方法,使用IXMLSerializable的自定義序列化是我唯一的解決方案。在我看來,我還會添加一個Version字段,我可以用它來指導反序列化。使用ISerializable時我們做類似的事情。真正的班級有大約15個領域。我想知道是否可以爲一個字段寫解串器代碼? – Mitch

2

您可以使用屬性來改變周圍的節點名和隱藏XML序列化的元素,解析手動只是一個元素:

public class IOPoint 
{ 
public string Name {get; set;} 

[XmlIgnore] 
public TypeEnum TypeEnum {get; set;} 

[XmlElement("TypeEnum")] 
public string LegacyTypeEnum 
{ 
    get { return this.TypeEnum.ToString(); } 
    set 
    { 
    try 
    { 
    this.TypeEnum = (TypeEnum)Enum.Parse(typeof(TypeEnum),value); 
    } 
    catch(ArgumentException) 
    { 
    // Handle "Humidity" 
    } 
    catch(OverflowException) 
    { 
    } 
    } 
} 
} 

每評論似乎有些混亂; here is a worked example作爲Visual Studio 2010項目。此方法是手動解析對象的一個​​屬性(仍利用XmlSerializer執行XML解析)的簡單方法。

+0

將枚舉值序列化爲一個字符串而不是枚舉,如果我還沒有我需要讀取的XML文件,這將是一個好主意。這些現有文件具有元素,我仍然需要讀取TypeEnum字段的值並相應地執行操作。一個理想的解決方案是在嘗試對溼度值進行反序列化時捕獲異常。但是,你放在反序列化器上的異常處理程序都沒有發現這個錯誤。 – Mitch

+0

我已經包含了一個可編譯的示例來演示它的工作原理和工作原理。 – user423430