後進一步琢磨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
忽略)。
我還沒有考慮其他缺點嗎?
我想問一個問題:你有什麼用例需要在未序列化的數據合約中的屬性? – Joe 2012-02-28 22:49:20
Joe:這個問題來自一個真實的案例,其中對象的內部狀態必須由序列化數據構建。存儲內部狀態將是多餘的。該示例高度簡化以突出DataContractSerializer繞過標準對象初始化(構造函數和字段初始值設定項)的核心問題,並試圖找到最佳設計模式來處理這一事實。 – 2012-02-28 22:57:07
我對這種行爲非常熟悉,我們被它咬了一兩次。但絕大多數我們的數據合同並不需要這種複雜的計算狀態。我的觀點是:如果你的數據約定類中有任何真正的邏輯,那麼這個邏輯可能不屬於那裏。或者,您可以存儲一個簡單的標誌字段,該標誌字段指示對象是否通過構造函數構造(只需在構造函數中設置非序列化的bool),然後在訪問非序列化屬性時使用標誌... – Joe 2012-02-28 23:32:45