試著用以下程式將一個有實作INotifyPropertyChanged介面的物件序列化:

BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, s);

結果傳回以下錯誤:

System.Runtime.Serialization.SerializationException was unhandled by user code  Message="Type 'System.ComponentModel.ReflectPropertyDescriptor' in Assembly 'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable."

由於之前沒加入PropertyChanged PropertyChangedEventHandler前序列化沒問題,理所當然它是頭號嫌犯,於是我加上[NonSerialized] Attribute:

[NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;

但變成編譯時出錯:

Attribute 'NonSerialized' is not valid on this declaration type. It is valid on 'field' declarations only.

爬文後,在MSDN論壇找到相關討論,原來要宣告成[field:NonSerialized]才可以。

至於前方的field什麼碗粿? 本草綱目MSDN文件有記載,它是屬性目標(Attribute Targets)標示,原因是同一個Attribute用在同一個Method宣告時,可以標示的目標可能有多個,例如: 方法本身或是傳回值,為了明確表達Attribute適用的對象為何,就可以加上type, method, field等修飾字排除語意模糊之處。而在本例中,加註field會將掛在EventHandler底下的Delegate都標為不可序列化。(補充資料)


Comments

# by 蹂躪

這問題我也碰過,不過不清楚為何.NET會要序列化EventHandler,使用上發現也不是所有的Event都會發生這問題。C#還有這個解法,在VB.NET中就沒有得用了,好像得自定義EventHandler才能解決。

Post a comment