1

DataContractDataMember屬性也可以用於通過使用DataContractSerializer將對象序列化到文件和用於反序列化。假設我們有一個具有以下私有字段和公共屬性的類。是否應用DataMember屬性在屬性中引發異常的良好做法?

public class MyClass 
{ 
    private int positiveValue; 

    public int PositiveValue 
    { 
     get { return positiveValue; } 
     set 
     { 
      if (value < 1) 
       throw new ArgumentOutOfBoundException(...); 
      positiveValue = value; 
     } 
    } 
} 

現在假設我們有一個包含預先序列化對象的狀態的XML文件,並假定用戶已修改該文件,指定一個不正確的值(即非正值)爲PositiveValue屬性。在反序列化過程中,將拋出異常,因爲文件中的值是無效的。

假設我們想從一個文件反序列化MyClass對象的列表:如果某個對象無效,則拋出異常。是否有可能確保DataContractSerializer忽略無效對象?此外,考慮到剛剛解釋的問題,是否在DataMember屬性應用的屬性中引發異常是一種很好的做法?

+1

我所做的是加載壞數據,然後有邏輯來標記它,以便用戶可以修復它。而邏輯不處理錯誤的數據。加載文件將有不好的數據。如果用戶將XML插入,我不想再回到XML,因爲它們可能會將其插入甚至不是有效的XML。 – Paparazzi

回答

1

就列表而言,不可以讓DCS忽略無效對象。如果發生異常,則整個反序列化會中止。如果它不扔,它會被添加到你的列表中。

我會考慮檢查反序列化後的有效性。在某些情況下,您可能只能說「忽略列表中的無效項」,但坦率地說,在大多數情況下,如果存在任何問題,您只是想拒絕整個事情。

2

如果要在設置屬性時驗證數據,但希望在反序列化期間繞過這些驗證,則可以使用DataMemberAttribute而不是屬性標記屬性的後備字段。這將導致DataContractSerializer直接在字段(而不是屬性)中設置值,並且不會拋出任何驗證異常。

[DataMember] 
private int positiveValue; 

public int PositiveValue 
{ 
    get { return positiveValue; } 
    set 
    { 
     if (value < 1) 
      throw new ArgumentOutOfBoundException(...); 
     positiveValue = value; 
    } 
} 

請注意,支持字段可以是私人的(否則,屬性沒有多大意義)。這適用於DataContractSerializer

此外,考慮到剛剛解釋的問題,在DataMember屬性應用的屬性中引發異常是一種很好的做法嗎?

這取決於是否允許在應用程序中使用無效數據的對象。不允許設置無效數據的優點是,每次使用時都不必檢查對象,但在這種情況下,您必須檢查任何用戶輸入並在加載數據時爲異常做好準備。但是,我不認爲在數據成員屬性中拋出異常是錯誤的。這只是設計決定的問題。

相關問題