程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#編程總結(一)序列化

C#編程總結(一)序列化

編輯:關於C#

序列化是將對象狀態轉換為可保持或傳輸的格式的過程。與序列化相對的是反序列化,它將流轉換為 對象。這兩個過程結合起來,可以輕松地存儲和傳輸數據。

幾種序列化技術:

1)二進制序列化保持類型保真度,這對於在應用程序的不同調用之間保留對象 的狀態很有用。例如,通過將對象序列化到剪貼板,可在不同的應用程序之間共享對象。您可以將對象 序列化到流、磁盤、內存和網絡等等。遠程處理使用序列化“通過值”在計算機或應用程序 域之間傳遞對象。

2)XML 序列化僅序列化公共屬性和字段,且不保持類型保真度。當您要提供或使 用數據而不限制使用該數據的應用程序時,這一點是很有用的。由於 XML 是一個開放式標准,因此,對 於通過 Web 共享數據而言,這是一個很好的選擇。SOAP 同樣是一個開放式標准,這使它也成為一個頗 具吸引力的選擇。

3)使用提供的數據協定,將類型實例序列化和反序列化為 XML 流或文檔(或者JSON格式)。常應用 於WCF通信。

BinaryFormatter

序列化可被定義為將對象的狀態存儲到存儲媒介中的過程。在此過程中,對象的公共字段和私有字段 以及類的名稱(包括包含該類的程序集)都被轉換為字節流,然後寫入數據流。在以後反序列化該對象 時,創建原始對象的精確復本。

1、使一個類可序列化的最簡單方式是按如下所示使用 Serializable 屬性標記。

2、有選擇的序列化

通過用 NonSerialized 屬性標記成員變量,可以防止它們被序列化

3、自定義序列化

1) 在序列化期間和之後運行自定義方法

最佳做法也是最簡單的方法(在 .Net Framework 2.0 版 中引入),就是在序列化期間和之後將下列屬性應用於用於更正數據的方法:

OnDeserializedAttribute

OnDeserializingAttribute

OnSerializedAttribute

OnSerializi ngAttribute

具體事例如下:

// This is the object that will be serialized and deserialized.
[Serializable()]        
public class TestSimpleObject  
{
    // This member is serialized and deserialized with no change.
    public int member1;
    
    // The value of this field is set and reset during and 
    // after serialization.
    private string member2;
    
    // This field is not serialized. The OnDeserializedAttribute 
    // is used to set the member value after serialization.
    [NonSerialized()] 
    public string member3; 
    
    // This field is set to null, but populated after deserialization.
    private string member4;
    
    // Constructor for the class.
    public TestSimpleObject() 
    {
        member1 = 11;
        member2 = "Hello World!";
        member3 = "This is a nonserialized value";
        member4 = null;
    }
    
    public void Print() 
    {
        Console.WriteLine("member1 = '{0}'", member1);
        Console.WriteLine("member2 = '{0}'", member2);
        Console.WriteLine("member3 = '{0}'", member3);
        Console.WriteLine("member4 = '{0}'", member4);
    }
    
    [OnSerializing()]
    internal void OnSerializingMethod(StreamingContext context)
    {
        member2 = "This value went into the data file during serialization.";
    }
    
    [OnSerialized()]
    internal void OnSerializedMethod(StreamingContext context)
    {
        member2 = "This value was reset after serialization.";
    }
    
    [OnDeserializing()]
    internal void OnDeserializingMethod(StreamingContext context)
    {
        member3 = "This value was set during deserialization";
    }
    
    [OnDeserialized()]
    internal void OnDeserializedMethod(StreamingContext context)
    {
        member4 = "This value was set after deserialization.";
    }    
}

2) 實現 ISerializable 接口

對於用 Serializable 屬性標記且在類級別上或其構造函數上具有聲明性或命令性安全的類,不應使 用默認序列化。相反,這些類應始終實現 ISerializable 接口。實現 ISerializable 涉及實現 GetObjectData 方法以及在反序列化對象時使用的特殊構造函數。

具體實例如下:

[Serializable]
public class MyObject : ISerializable 
{
  public int n1;
  public int n2;
  public String str;
    
  public MyObject()
  {
  }
    
  protected MyObject(SerializationInfo info, StreamingContext context)
  {
    n1 = info.GetInt32("i");
    n2 = info.GetInt32("j");
    str = info.GetString("k");
  }
[SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter =true)]
  public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
  {
    info.AddValue("i", n1);
    info.AddValue("j", n2);
    info.AddValue("k", str);
  }
}

注意:

在反序列化一個對象時不調用構造函數。出於性能方面的原因對反序列化施加了該約束。但是,這違 反了運行庫與對象編寫器之間的一些通常約定,開發人員應確保他們在將對象標記為可序列化時了解其 後果。

SoapFormatter

以 SOAP 格式將對象或整個連接對象的圖形序列化和反序列化。基本用法類似於BinaryFormatter。 SoapFormatter 和 BinaryFormatter 兩個類實現 IRemotingFormatter 接口以支持遠程過程調用 (RPC) ,實現 IFormatter 接口(由 IRemotingFormatter 繼承)以支持對象圖形的序列化。SoapFormatter 類還支持對 ISoapMessage 對象進行 RPC,而不必使用 IRemotingFormatter 功能。

XmlSerializer

將對象序列化到 XML 文檔中和從 XML 文檔中反序列化對象。XmlSerializer 使您得以控制如何將對 象編碼到 XML 中。

XML 序列化是將對象的公共屬性 (Property) 和字段轉換為序列格式(這裡是指 XML)以便存儲或傳 輸的過程。反序列化則是從 XML 輸出中重新創建原始狀態的對象。因此,可以將序列化視為將對象的狀 態保存到流或緩沖區的方法。例如,ASP.NET 使用 XmlSerializer 類對 XML Web services 消息進行編 碼。

例子:

C#代碼

public class MyClass
{
    public MyObject MyObjectProperty;
}
public class MyObject
{
    public string ObjectName;
}

序列化後的XML  

<MyClass>

 <MyObjectProperty>

 <ObjectName>My String</ObjectName>

 </MyObjectProperty>

</MyClass>

還可以通過標記來控制XML的輸出

1、默認值

DefaultValueAttribute

2、過濾某屬性或字段

XmlIgnoreAttribute

3、重寫默認序列化邏輯

具體可見:http://msdn.microsoft.com/zh- cn/library/system.xml.serialization.xmlattributeoverrides(v=vs.80).aspx

其他控制手段,具體可見http://msdn.microsoft.com/zh-cn/library/83y7df3e(v=vs.80).aspx

4、將對象序列化為 SOAP 編碼的 XML 流

http://msdn.microsoft.com/zh-cn/library/bd04skah(v=vs.80).aspx

注意

XML 序列化不轉換方法、索引器、私有字段或只讀屬性(只讀集合除外)。要序列化對象的所有字段 和屬性(公共的和私有的),請使用 BinaryFormatter,而不要使用 XML 序列化。

DataContractSerializer

使用提供的數據協定,將類型實例序列化和反序列化為 XML 流或文檔。 此類不能被繼承。

DataContractSerializer 用於序列化和反序列化在 Windows Communication Foundation (WCF) 消 息中發送的數據。 通過將 DataContractAttribute 屬性 (Attribute) 應用於類,而將 DataMemberAttribute 屬性 (Attribute) 應用於類成員,可以指定要序列化的屬性 (Property) 和字段 。

使用步驟:

1)DataContractSerializer 與 DataContractAttribute 和 DataMemberAttribute 類結合使用。

要准備序列化某個類,請將 DataContractAttribute 應用於該類。 對於返回要序列化的數據的類的 每個成員,請應用 DataMemberAttribute。 您可以序列化字段和屬性,而無論其可訪問性級別是什麼: private、protected、internal、protected internal 或 public。

2)添加到已知類型的集合中

在序列化或反序列化對象時,DataContractSerializer 必須“已知”該類型。 首先,創 建一個實現 IEnumerable<T>(如 List<T>)的類實例,並將已知類型添加到集合中。 然 後,使用接受 IEnumerable<T>(例如, [M:System.Runtime.Serialization.DataContractSerializer.#ctor (System.Type,System.Collections.Generic.IEnumerable{System.Type}])的重載之一創建 DataContractSerializer 的實例。

具體實例:

namespace DataContractSerializerExample
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Runtime.Serialization;
    using System.Xml;
    
    // You must apply a DataContractAttribute or SerializableAttribute
    // to a class to have it serialized by the DataContractSerializer.
    [DataContract(Name = "Customer", Namespace = 

"http://www.contoso.com")]
    class Person : IExtensibleDataObject
    {
        [DataMember()]
        public string FirstName;
        [DataMember]
        public string LastName;
        [DataMember()]
        public int ID;
    
        public Person(string newfName, string newLName, int newID)
        {
            FirstName = newfName;
            LastName = newLName;
            ID = newID;
        }
    
        private ExtensionDataObject extensionData_Value;
    
        public ExtensionDataObject ExtensionData
        {
            get
            {
                return extensionData_Value;
            }
            set
            {
                extensionData_Value = value;
            }
        }
    }
    
    public sealed class Test
    {
        private Test() { }
    
        public static void Main()
        {
            try
            {
                WriteObject("DataContractSerializerExample.xml");
                ReadObject("DataContractSerializerExample.xml");
    
            }
    
            catch (SerializationException serExc)
            {
                Console.WriteLine("Serialization Failed");
                Console.WriteLine(serExc.Message);
            }
            catch (Exception exc)
            {
                Console.WriteLine(

                "The serialization operation failed: {0} StackTrace: {1}",
                exc.Message, exc.StackTrace);
            }
    
            finally
            {
                Console.WriteLine("Press <Enter> to exit....");
                Console.ReadLine();
            }
        }
    
        public static void WriteObject(string fileName)
        {
            Console.WriteLine(
                "Creating a Person object and serializing it.");
            Person p1 = new Person("Zighetti", "Barbara", 101);
            FileStream writer = new FileStream(fileName, FileMode.Create);
            DataContractSerializer ser =
                new DataContractSerializer(typeof(Person));
            ser.WriteObject(writer, p1);
            writer.Close();
        }
    
        public static void ReadObject(string fileName)
        {
            Console.WriteLine("Deserializing an instance of the object.");
            FileStream fs = new FileStream(fileName,
            FileMode.Open);
            XmlDictionaryReader reader =
                XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
            DataContractSerializer ser = new DataContractSerializer(typeof(Person));
    
            // Deserialize the data and read it from the instance.
            Person deserializedPerson =
                (Person)ser.ReadObject(reader, true);
            reader.Close();
            fs.Close();
            Console.WriteLine(String.Format("{0} {1}, ID: {2}",
            deserializedPerson.FirstName, deserializedPerson.LastName,
            deserializedPerson.ID));
        }
    }

查看本欄目

DataContractJsonSerializer

將對象序列化為 JavaScript 對象表示法 (JSON),並將 JSON 數據反序列化為對象。 此類不能被繼 承。

具體使用與DataContractSerializer類似。這裡不再贅述。

下面對這些方法的使用做了匯總,希望能給大家帶來一些幫助。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
using System.Xml.Serialization;
    
namespace SerializerSample
{
    /// <summary>
    /// 序列化幫助類
    /// </summary>
    public sealed class SerializeHelper
    { 
        #region DataContract序列化
        /// <summary>
        /// DataContract序列化
        /// </summary>
        /// <param name="value"></param>
        /// <param name="knownTypes"></param>
        /// <returns></returns>
        public static string SerializeDataContract(object value, List<Type> knownTypes = null)
        {
            DataContractSerializer dataContractSerializer = new DataContractSerializer(value.GetType(), knownTypes);
    
            using (MemoryStream ms = new MemoryStream())
            {
                dataContractSerializer.WriteObject(ms, value);
                ms.Seek(0, SeekOrigin.Begin);
                using (StreamReader sr = new StreamReader(ms))
                {
                    return sr.ReadToEnd();
                }
            }
        }
        /// <summary>
        /// DataContract反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static T DeserializeDataContract<T>(string xml)
        {
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(T));
                return (T)serializer.ReadObject(ms);
            }
        }
        #endregion
    
        #region DataContractJson序列化
        /// <summary>
        ///  DataContractJson序列化
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string SerializeDataContractJson(object value)
        {
            DataContractJsonSerializer dataContractSerializer = new DataContractJsonSerializer(value.GetType());
            using (MemoryStream ms = new MemoryStream())
            {                
                dataContractSerializer.WriteObject(ms, value);
                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }
        /// <summary>
        ///  DataContractJson反序列化
        /// </summary>
        /// <param name="type"></param>
        /// <param name="str"></param>
        /// <returns></returns>
        public static object DeserializeDataContractJson(Type type, string str)
        {
            DataContractJsonSerializer dataContractSerializer = new DataContractJsonSerializer(type);
            using (MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(str)))
            {
                return dataContractSerializer.ReadObject(ms);
            }
        }
        /// <summary>
        /// DataContractJson反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public T DeserializeDataContractJson<T>(string json)
        {
            DataContractJsonSerializer dataContractSerializer = new DataContractJsonSerializer(typeof(T));
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
            {
                return (T)dataContractSerializer.ReadObject(ms);
            }
        }
        #endregion
    
        #region XmlSerializer序列化
        /// <summary>
        /// 將對象序列化到 XML 文檔中和從 XML 文檔中反序列化對象。XmlSerializer 使您得以控制如何將對象編碼到 XML 中。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string SerializeXml(object value)
        {
            XmlSerializer serializer = new XmlSerializer(value.GetType());
            using (MemoryStream ms = new MemoryStream())
            {
                serializer.Serialize(ms, value);
                ms.Seek(0, SeekOrigin.Begin);
                using (StreamReader sr = new StreamReader(ms))
                {
                    return sr.ReadToEnd();
                }
            }
        }
        /// <summary>
        ///  XmlSerializer反序列化
        /// </summary>
        /// <param name="type"></param>
        /// <param name="str"></param>
        /// <returns></returns>
        public static object DeserializeXml(Type type, string str)
        {
            XmlSerializer serializer = new XmlSerializer(type);
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(str);
            using (MemoryStream ms = new MemoryStream(bytes))
            {
                return serializer.Deserialize(ms);
            }
        }
        #endregion
    
        #region BinaryFormatter序列化
        /// <summary>
        /// BinaryFormatter序列化
        /// 必須類型必須標記為Serializable
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string SerializeBinaryFormatter(object obj)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream())
            {
                formatter.Serialize(ms,obj);
                byte[] bytes = ms.ToArray();
                obj = formatter.Deserialize(new MemoryStream(bytes));
                //如果是UTF8格式,則反序列化報錯。可以用Default格式,不過,建議還是傳參為byte數組比較好
                return Encoding.Default.GetString(bytes);
            }
        }
    
        /// <summary>
        /// BinaryFormatter反序列化
        /// 必須類型必須標記為Serializable
        /// </summary>
        /// <param name="serializedStr"></param>
        /// <returns></returns>
        public static T DeserializeBinaryFormatter<T>(string serializedStr)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            byte[] bytes = Encoding.Default.GetBytes(serializedStr);
            using (MemoryStream ms = new MemoryStream(bytes))
            {
                return (T)formatter.Deserialize(ms);
            }
        }
        #endregion 
    
        #region SoapFormatter序列化
        /// <summary>
        /// SoapFormatter序列化
        /// 必須類型必須標記為Serializable
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string SerializeSoapFormatter(object obj)
        {
            SoapFormatter formatter = new SoapFormatter();
            using (MemoryStream ms = new MemoryStream())
            {
                formatter.Serialize(ms, obj);
                byte[] bytes = ms.ToArray();
                return Encoding.UTF8.GetString(bytes);
            }
        }
        /// <summary>
        /// SoapFormatter反序列化
        /// 必須類型必須標記為Serializable
        /// </summary>
        /// <param name="serializedStr"></param>
        /// <returns></returns>
        public static T DeserializeSoapFormatter<T>(string serializedStr)
        {
            SoapFormatter formatter = new SoapFormatter();
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(serializedStr)))
            {
                return (T)formatter.Deserialize(ms);
            }
        }
        #endregion
    }
}

具體的實例代碼如下:

下載:http://files.cnblogs.com/yank/SerializerSample.rar

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved