c#.net實體類序列化方法  為什麼要序列化

iDotNetSpace發表於2010-01-07
  提到為了傳遞資料,需要把作為載體的實體類序列化,好好的找了一些序列化方面的介紹。感覺下面的這個介紹比較容易介紹!
  1.什麼是序列化
  序列化是將物件狀態轉換為可保持或傳輸的格式的過程,在序列化過程中,物件的公共欄位和私有欄位以及類的名稱(包括包含該類的程式集)都被轉換為位元組流,然後寫入資料流。與序列化相對的是反序列化,它將流轉換為物件。這兩個過程結合起來,可以輕鬆地儲存和傳輸資料。
  2.為什麼使用序列化
  a. 一個原因是將物件的狀態保持在儲存媒體中,以便可以在以後重新建立精確的副本。
   我們經常需要將物件的欄位值儲存到磁碟中,並在以後檢索此資料。儘管不使用序列化也能完成這項工作,但這種方法通常很繁瑣而且容易出錯,並且在需要跟蹤 物件的層次結構時,會變得越來越複雜。可以想象一下編寫包含大量物件的大型業務應用程式的情形,程式設計師不得不為每一個物件編寫程式碼,以便將欄位和屬性儲存 至磁碟以及從磁碟還原這些欄位和屬性。序列化提供了輕鬆實現這個目標的快捷方法。
  b.另一個原因是通過值將物件從一個應用程式域傳送到另一個應用程式域中。
  例如,序列化可用於在 ASP.NET 中儲存會話狀態並將物件複製到 Windows 窗體的剪貼簿中。遠端處理還可以使用序列化通過值將物件從一個應用程式域傳遞到另一個應用程式域中。
   公共語言執行時 (CLR) 管理物件在記憶體中的分佈,.NET 框架則通過使用反射提供自動的序列化機制。物件序列化後,類的名稱、程式集以及類例項的所有資料成員均被寫入儲存媒體中。物件通常用成員變數來儲存對其他 例項的引用。類序列化後,序列化引擎將跟蹤所有已序列化的引用物件,以確保同一物件不被序列化多次。.NET 框架所提供的序列化體系結構可以自動正確處理物件圖表和迴圈引用。對物件圖表的唯一要求是,由正在進行序列化的物件所引用的所有物件都必須標記為 Serializable(請參閱基本序列化)。否則,當序列化程式試圖序列化未標記的物件時將會出現異常。
  當反序列化已序列化的類時,將重新建立該類,並自動還原所有資料成員的值。
  3.如何實現物件的序列化及反序列化
  要實現物件的序列化,首先要保證該物件可以序列化。而且,序列化只是將物件的屬性進行有效的儲存,對於物件的一些方法則無法實現序列化的。
  實現一個類可序列化的最簡便的方法就是增加Serializable屬性標記類。如:
  [Serializable()]
  public class MEABlock
  {
  private int m_ID;
  public string Caption;
  public MEABlock()
  {
  ///建構函式
  }
  }
  即可實現該類的可序列化。注意序列化的類必須為Public,否則不能夠被序列化。
  要將該類的例項序列化為到檔案中?.NET FrameWork提供了兩種方法:
  a .XML序列化
  使用 XmLSerializer 類,可將下列項序列化。
  公共類的公共讀/寫屬性和欄位
  實現 違規廣告ection 或 IEnumerable 的類。(注意只有集合會被序列化,而公共屬性卻不會。)
  XmlElement 物件。
  XmlNode 物件。
  DataSet 物件。
  要實現上述類的例項的序列化,可參照如下例子:
  MEABlock myBlock = new MEABlock();
  // Insert code to set properties and fields of the object.
  XmlSerializer mySerializer = new XmlSerializer(typeof(MEABlock));
  // To write to a file, create a StreamWriter object.
  StreamWriter myWriter = new StreamWriter("myFileName.xml");
  mySerializer.Serialize(myWriter, MEABlock);
  需要注意的是XML序列化只會將public的欄位儲存,對於私有欄位不予於儲存。
  生成的XML檔案格式如下:
  
  Test
  

  對於物件的反序列化,則如下:
  MEABlock myBlock;
  // Constructs an instance of the XmlSerializer with the type
  // of object that is being deserialized.
  XmlSerializer mySerializer = new XmlSerializer(typeof(MEABlock));
  // To read the file, creates a FileStream.
  FileStream myFileStream = new FileStream("myFileName.xml", FileMode.Open);
  // Calls the Deserialize method and casts to the object type.
  myBlock = (MEABlock)mySerializer.Deserialize(myFileStream)
  b. 二進位制序列化
  與XML序列化不同的是,二進位制序列化可以將類的例項中所有欄位(包括私有和公有)都進行序列化操作。這就更方便、更準確的還原了物件的副本。
  要實現上述類的例項的序列化,可參照如下例子:
  MEABlock myBlock = new MEABlock();
  // Insert code to set properties and fields of the object.
  IFormatter formatter = new BinaryFormatter();
  Stream stream = new FileStream("MyFile.bin",FileMode.Create,FileAccess.Write, FileShare.None);
  formatter.Serialize(stream, myBlock);
  stream.Close();
  對於物件的反序列化,則如下:
  IFormatter formatter = new BinaryFormatter();
  Stream stream = new FileStream("MyFile.bin", FileMode.Open,FileAccess.Read, FileShare.Read);
  MEABlock myBlock = (MEABlock) formatter.Deserialize(stream);
  stream.Close();
  4、如何變相實現自定義視覺化控制元件的序列化、反序列化
  對於WinForm中自定義控制元件,由於繼承於System.Windows.Form類,而Form類又是從MarshalByRefObject繼承的,窗體本身無法做到序列化,窗體的實現基於Win32下GUI資源,不能脫離當前上下文存在。
  當然可以採用變通的方法實現控制元件的序列化。這裡採用的是記憶類模型。
  定義記憶類(其實就是一個可序列化的實體類)用於記錄控制元件的有效屬性,需要序列化控制元件的時候,只需要將該控制元件的例項Copy到記憶類,演變成序列化儲存該記憶類的操作。
  反序列化是一個逆過程。將資料流反序列化成為該記憶類,再根據該記憶類的屬性生成控制元件例項。而對於控制元件的一些事件、方法則可以繼續使用。
  wwf之所以強調要把類例項化,就是因為工作流和應用程式是在不同的執行緒中。二者之間需要用類作為傳遞資料的載體的話,就需要把該類定義為public序列化為二進位制傳輸。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-624595/,如需轉載,請註明出處,否則將追究法律責任。

相關文章