2016-08-14 74 views
1

每當我遇到這個屬性,我總是看到這樣的用法:DataContract祕密行爲?

[DataContract] 
class DataTransferObject 
{ 
    [DataMember] 
    public int Value {get;set;} 
} 

而且在這個例子中所有繼承的成員應適用的DataMember屬性爲每個屬性或領域,這可能導致非常笨拙和poilerplate代碼。但是,最近我發現(也許祕密功能?)用它的一個非常優雅的方式:

[DataContract] 
public abstract class DTOBase 
{ 
} 

public class MyDTO : DTOBase 
{ 
    public int Value {get;set;} 

    public MyDTO(){} //important part is here 
} 

重要的部分:你應該總是明確定義參數構造函數,否則將無法正確序列化。

是的。它序列化其所有公共成員,不管多深將繼承,而無需將屬性應用於成員或類定義。

這是不知何故記錄在某處(我沒有找到)?因爲,我非常支持可以避免多少樣板文件。

回答

2

實際上,如果你不想要,你不需要使用DataContractDataMember屬性,但是它們給你靈活定義什麼需要序列化和如何。

我建議從文章Serializable Types on MSDN開始,它有很多關於Data Contract串行器如何工作的信息。這裏是第一段落2,證明你不需要使用屬性:

默認情況下,DataContractSerializer的序列化的所有公開可見 類型。

該類型的所有公共讀/寫屬性和字段都是 序列化的。您可以通過將 DataContractAttribute和DataMemberAttribute屬性應用於 和成員類型來更改默認行爲。此功能在您的 類型不受您控制並且無法修改爲添加 屬性的情況下非常有用。 DataContractSerializer可識別這種「未標記」的 類型。

適用於你的情況主要規則是:

  • DataContract屬性不會被繼承。你可以在你的基類DTOBase上應用它,也可以不在你的基類MyDTO中忽略它。您可以從DTOBase類中刪除DataContract屬性,結果將相同。
  • 如果您在類中使用DataContract屬性,則只有具有DataMember屬性的成員纔會被序列化。這就是您的第一個示例中DataTransferObject類中發生的情況。
  • 如果您沒有在類上使用DataContract屬性,則會對所有類的公共成員進行序列化。這是您的班級MyDTO發生的情況。