2012-02-28 42 views
1

後進一步琢磨DataContractSerializer not calling constructors or static field initializers的影響,它似乎是一個清潔器設計圖案具有屬性自初始化這樣的:DataContractSerializer的和初始化

private ObservableCollection<object> myObjects; 
public ObservableCollection<object> MyObjects 
{ 
    get 
    { 
     if (myObjects == null) myObjects = new ObservableCollection<object>(); 
     return myObjects; 
    } 
    set 
    { 
     myObjects = value; 
    } 
} 

,而不是提供兩個初始化路徑是這樣的:

public MyClass() 
{ 
    InitializeClass(); 
} 

[OnDeserialized()] 
private void OnDeserialized(StreamingContext c) 
{ 
    InitializeClass(); 
} 

private void InitializeClass() 
{ 
    // Note here I can still use a field. 
    // Self-initialization requires a property. 
    myObjects = new ObservableCollection<objects>(); 
} 

我主要關心的是後者的模式不會失敗,如果忘記了特殊的OnDeserialized初始化,除非這些單元測試是專門設計用於知道它們可能在某些時候與DataContractSerializer一起使用。

那感覺太糾結了。

自我初始化方法的一個缺點是它需要屬性而不是字段(因爲字段初始值設定項被DataContractSerializer忽略)。

我還沒有考慮其他缺點嗎?

+0

我想問一個問題:你有什麼用例需要在未序列化的數據合約中的屬性? – Joe 2012-02-28 22:49:20

+0

Joe:這個問題來自一個真實的案例,其中對象的內部狀態必須由序列化數據構建。存儲內部狀態將是多餘的。該示例高度簡化以突出DataContractSerializer繞過標準對象初始化(構造函數和字段初始值設定項)的核心問題,並試圖找到最佳設計模式來處理這一事實。 – 2012-02-28 22:57:07

+0

我對這種行爲非常熟悉,我們被它咬了一兩次。但絕大多數我們的數據合同並不需要這種複雜的計算狀態。我的觀點是:如果你的數據約定類中有任何真正的邏輯,那麼這個邏輯可能不屬於那裏。或者,您可以存儲一個簡單的標誌字段,該標誌字段指示對象是否通過構造函數構造(只需在構造函數中設置非序列化的bool),然後在訪問非序列化屬性時使用標誌... – Joe 2012-02-28 23:32:45

回答