C#對象序列化與反序列化zz

来源:http://www.cnblogs.com/xpvincent/archive/2016/08/30/5821769.html
-Advertisement-
Play Games

C#對象序列化與反序列化(轉載自:http://www.cnblogs.com/LiZhiW/p/3622365.html) 1. 對象序列化的介紹.................................................................... 2 (1) .... ...


 

C#對象序列化與反序列化(轉載自:http://www.cnblogs.com/LiZhiW/p/3622365.html)

1. 對象序列化的介紹.................................................................... 2

(1) .NET支持對象序列化的幾種方式................................. 2

(2) 幾種序列化的區別............................................................ 2

(3) 使用特性對序列化的控制............................................... 2

2. 使用二進位序列化和反序列化............................................... 2

(1) 二進位序列化與反序列化的程式示例.......................... 2

(2) 總結..................................................................................... 3

3. 使用SOAP方式序列化和反序列化........................................ 3

(1) SOAP序列化與反序列化的程式示例............................. 3

(2) 總結..................................................................................... 4

4. 使用XML方式序列化和反序列化.......................................... 4

(1) XML序列化與反序列化的程式示例............................... 4

(2) 總結..................................................................................... 5

5. XML序列化對象詳解................................................................ 5

(1) 說明..................................................................................... 5

(2) 使用XmlElement(預設值)............................................. 5

(3) 使用XmlAttribute.......................................................... 5

(4) 使用XmlText..................................................................... 6

(5) 使用XmlType和XmlAttribute(重命名節點名稱).. 6

(6) 列表和數組的序列化........................................................ 6

(7) 列表和數組的做為數據成員的序列化.......................... 7

(8) 類型繼承與反序列化........................................................ 9

(9) 排除不需要序列化的成員............................................. 10

(10) 強制指定成員的序列化順序....................................... 10

(11) 自定義序列化行為........................................................ 11

(12) 序列化設置XML命名空間........................................... 11

(13) XML的使用建議............................................................ 11

(14) 反序列化的使用總結................................................... 12

6. 自定義序列化(僅適用於二進位與SOAP).......................... 12

(1) 自定義序列化的實現方式............................................. 12

(2) 示常式序.......................................................................... 12

1.對象序列化的介紹

(1).NET支持對象序列化的幾種方式

二進位序列化:對象序列化之後是二進位形式的,通過BinaryFormatter類來實現的,這個類位於System.Runtime.Serialization.Formatters.Binary命名空間下。

SOAP序列化:對象序列化之後的結果符合SOAP協議,也就是可以通過SOAP 協議傳輸,通過System.Runtime.Serialization.Formatters.Soap命名空間下的SoapFormatter類來實現的。

XML序列化:對象序列化之後的結果是XML形式的,通過XmlSerializer 類來實現的,這個類位於System.Xml.Serialization命名空間下。XML序列化不能序列化私有數據。

(2)幾種序列化的區別

二進位格式和SOAP格式可序列化一個類型的所有可序列化欄位,不管它是公共欄位還是私有欄位。XML格式僅能序列化公共欄位或擁有公共屬性的私有欄位,未通過屬性公開的私有欄位將被忽略。

使用二進位格式序列化時,它不僅是將對象的欄位數據進行持久化,也持久化每個類型的完全限定名稱和定義程式集的完整名稱(包括包稱、版本、公鑰標記、區域性),這些數據使得在進行二進位格式反序列化時亦會進行類型檢查。SOAP格式序列化通過使用XML命名空間來持久化原始程式集信息。而XML格式序列化不會保存完整的類型名稱或程式集信息。這便利XML數據表現形式更有終端開放性。如果希望儘可能延伸持久化對象圖的使用範圍時,SOAP格式和XML格式是理想選擇。

(3)使用特性對序列化的控制

要讓一個對象支持.Net序列化服務,用戶必須為每一個關聯的類加上[Serializable]特性。如果類中有些成員不適合參與序列化(比如:密碼欄位),可以在這些域前加上[NonSerialized]特性。

2.使用二進位序列化和反序列化

(1)二進位序列化與反序列化的程式示例

    [Serializable]  //必須添加序列化特性

    public class Person

    {

        private string Name;//姓名

        private bool Sex;//性別,是否是男

        public Person(string name, bool sex)

        {

            this.Name = name;

            this.Sex = sex;

        }

        public override string ToString()

        {

            return "姓名:" + this.Name + "\t性別:" + (this.Sex ? "男" : "女");

        }

    }

    [Serializable]  //必須添加序列化特性

    public class Programmer : Person

    {

        private string Language;//編程語言

        public Programmer(string name, bool sex, string language) : base(name, sex)

        {

            this.Language = language;

        }

        public override string ToString()

        {

            return base.ToString() + "\t編程語言:" + this.Language;

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            //創建Programmer列表,並添加對象

            List<Programmer> list = new List<Programmer>();

            list.Add(new Programmer("李志偉", true, "C#"));

            list.Add(new Programmer("Coder2", false, "C++"));

            list.Add(new Programmer("Coder3", true, "Java"));

            //使用二進位序列化對象

            string fileName = @"D:\users\lizw\桌面\Programmers.dat";//文件名稱與路徑

            Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);

            BinaryFormatter binFormat = new BinaryFormatter();//創建二進位序列化器

            binFormat.Serialize(fStream, list);

            //使用二進位反序列化對象

            list.Clear();//清空列表

            fStream.Position = 0;//重置流位置

            list = (List<Programmer>)binFormat.Deserialize(fStream);//反序列化對象

            foreach (Programmer p in list)

            {

                Console.WriteLine(p);

            }

            Console.Read();

        }

    }

(2)總結

使用二進位序列化,必須為每一個要序列化的的類和其關聯的類加上[Serializable]特性,對類中不需要序列化的成員可以使用[NonSerialized]特性。

二進位序列化對象時,能序列化類的所有成員(包括私有的),且不需要類有無參數的構造方法。

使用二進位格式序列化時,它不僅是將對象的欄位數據進行持久化,也持久化每個類型的完全限定名稱和定義程式集的完整名稱(包括包稱、版本、公鑰標記、區域性),這些數據使得在進行二進位格式反序列化時亦會進行類型檢查。所以反序列化時的運行環境要與序列化時的運行環境要相同,否者可能會無法反序列化成功。

3.使用SOAP方式序列化和反序列化

(1)SOAP序列化與反序列化的程式示例

    [Serializable]  //必須添加序列化特性

    public class Person

    {

        private string Name;//姓名

        private bool Sex;//性別,是否是男

        public Person(string name, bool sex)

        {

            this.Name = name;

            this.Sex = sex;

        }

        public override string ToString()

        {

            return "姓名:" + this.Name + "\t性別:" + (this.Sex ? "男" : "女");

        }

    }

    [Serializable]  //必須添加序列化特性

    public class Programmer : Person

    {

        private string Language;//編程語言

        public Programmer(string name, bool sex, string language) : base(name, sex)

        {

            this.Language = language;

        }

        public override string ToString()

        {

            return base.ToString() + "\t編程語言:" + this.Language;

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            //實例化對象

            Programmer p = new Programmer("李志偉", true, "C、C#、C++、Java");

            //使用SOAP序列化對象

            string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑

            Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);

            SoapFormatter soapFormat = new SoapFormatter();//創建SOAP序列化器

            soapFormat.Serialize(fStream, p);//SOAP不能序列化泛型對象

            //使用SOAP反序列化對象

            fStream.Position = 0;//重置流位置

            p = null;

            p = (Programmer)soapFormat.Deserialize(fStream);

            Console.WriteLine(p);

            Console.Read();

        }

    }

(2)總結

SOAP序列化與二進位序列化的區別是:SOAP序列化不能序列化泛型類型。與二進位序列化一樣在序列化時不需要向序列化器指定序列化對象的類型。而XML序列化需要向XML序列化器指定序列化對象的類型。

4.使用XML方式序列化和反序列化

(1)XML序列化與反序列化的程式示例

    public class Person

    {

        public string Name;//姓名

        public bool Sex;//性別,是否是男

        public Person() { }//必須提供無參構造器,否則XmlSerializer將出錯

        public Person(string name, bool sex)

        {

            this.Name = name;

            this.Sex = sex;

        }

        public override string ToString()

        {

            return "姓名:" + this.Name + "\t性別:" + (this.Sex ? "男" : "女");

        }

    }

    public class Programmer : Person

    {

        public string Language;//編程語言

        public Programmer() { }//必須提供無參構造器,否則XmlSerializer將出錯

        public Programmer(string name, bool sex, string language) : base(name, sex)

        {

            this.Language = language;

        }

        public override string ToString()

        {

            return base.ToString() + "\t編程語言:" + this.Language;

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            //創建Programmer列表,並添加對象

            List<Programmer> list = new List<Programmer>();

            list.Add(new Programmer("李志偉", true, "C#"));

            list.Add(new Programmer("Coder2", false, "C++"));

            list.Add(new Programmer("Coder3", true, "Java"));

            //使用XML序列化對象

            string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑

            Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);

            XmlSerializer xmlFormat = new XmlSerializer(

typeof(List<Programmer>),

new Type[] { typeof(Programmer),typeof(Person) }

);//創建XML序列化器,需要指定對象的類型

            xmlFormat.Serialize(fStream, list);

            //使用XML反序列化對象

            fStream.Position = 0;//重置流位置

            list.Clear();

            list = (List<Programmer>)xmlFormat.Deserialize(fStream);

            foreach (Programmer p in list)

            {

                Console.WriteLine(p);

            }

            Console.Read();

        }

    }

(2)總結

使用XML序列化或反序列化時,需要對XML序列化器指定需要序列化對象的類型和其關聯的類型。

XML序列化只能序列化對象的公有屬性,並且要求對象有一個無參的構造方法,否者無法反序列化。

[Serializable]和[NonSerialized]特性對XML序列化無效!所以使用XML序列化時不需要對對象增加[Serializable]特性。

5.XML序列化對象詳解

(1)說明

本節主要介紹:使用特性控制對象序列化成XML文件的格式。

(2)使用XmlElement(預設值)

類聲明:

    public class Person

    {

        [XmlElement]

        public string Name;//使用[XmlElement]特性

        public bool Sex;//預設使用了[XmlElement]特性

        public Person() { }//必須提供無參構造器,否則XmlSerializer將出錯

    }

序列化生成的XML文件:

<Personxmlns:xsi="..."xmlns:xsd="...">

  <Name>李志偉</Name>

  <Sex>true</Sex>

</Person>

(3)使用XmlAttribute

類聲明:

    public class Person

    {

        [XmlElement]

        public string Name;

        [XmlAttribute]

        public bool Sex;

        public Person() { }//必須提供無參構造器,否則XmlSerializer將出錯

    }

序列化生成的XML文件:

<Personxmlns:xsi="..."xmlns:xsd="..."Sex="true">

  <Name>李志偉</Name>

</Person>

(4)使用XmlText

類聲明:

    public class Person

    {

        [XmlText]

        public string Name;

        [XmlAttribute]

        public bool Sex;

        public Person() { }//必須提供無參構造器,否則XmlSerializer將出錯

    }

序列化生成的XML文件:

<Personxmlns:xsi="..."xmlns:xsd="..."Sex="true">李志偉</Person>

(5)使用XmlType和XmlAttribute(重命名節點名稱)

類聲明:

    [XmlType("個人信息")]

    public class Person

    {

        [XmlAttribute("姓名")]

        public string Name;

        [XmlAttribute("性別")]

        public bool Sex;

        public Person() { }//必須提供無參構造器,否則XmlSerializer將出錯

    }

序列化生成的XML文件:

<個人信息xmlns:xsi="..."xmlns:xsd="..."姓名="李志偉"性別="true" />

(6)列表和數組的序列化

類聲明:

    [XmlType("個人信息")]

    public class Person

    {

        [XmlAttribute("姓名")]

        public string Name;

        [XmlAttribute("性別")]

        public bool Sex;

        public Person() { }//必須提供無參構造器,否則XmlSerializer將出錯

    }

    class Program

    {

        static void Main(string[] args)

        {

            Person p = new Person();

            p.Name = "李志偉";

            p.Sex = true;

            Person[] ps = new Person[3];

            ps[0] = p;

            ps[1] = p;

            ps[2] = p;

            //使用XML序列化對象

            string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑

            Stream fStream = new FileStream(fileName, FileMode.Create);

            XmlSerializer xmlFormat = new XmlSerializer(typeof(Person[]));

            xmlFormat.Serialize(fStream, ps);//序列化對象

            fStream.Dispose();//關閉文件

            Console.WriteLine("OK!");

            Console.Read();

        }

    }

序列化生成的XML文件:

<ArrayOf個人信息xmlns:xsi="..."xmlns:xsd="...">

  <個人信息姓名="李志偉"性別="true" />

  <個人信息姓名="李志偉"性別="true" />

  <個人信息姓名="李志偉"性別="true" />

</ArrayOf個人信息>

註意:發現此時的XML文件的根節點名稱變了。此時要重命名根節點應使用如下方式:

    [XmlType("個人信息")]

    public class Person

    {

        [XmlAttribute("姓名")]

        public string Name;

        [XmlAttribute("性別")]

        public bool Sex;

        public Person() { }//必須提供無參構造器,否則XmlSerializer將出錯

    }

    [XmlType("人員信息")]

    public class PersonArray : List<Person> { }

    class Program

    {

        static void Main(string[] args)

        {

            Person p = new Person();

            p.Name = "李志偉";

            p.Sex = true;

            PersonArray ps = new PersonArray();

            ps.Add(p);

            ps.Add(p);

            ps.Add(p);

            //使用XML序列化對象

            string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑

            Stream fStream = new FileStream(fileName, FileMode.Create);

            XmlSerializer xmlFormat = new XmlSerializer(typeof(PersonArray));

            xmlFormat.Serialize(fStream, ps);//序列化對象

            fStream.Dispose();//關閉文件

            Console.WriteLine("OK!");

            Console.Read();

        }

    }

序列化生成的XML文件:

<人員信息xmlns:xsi="..."xmlns:xsd="...">

  <個人信息姓名="李志偉"性別="true" />

  <個人信息姓名="李志偉"性別="true" />

  <個人信息姓名="李志偉"性別="true" />

</人員信息>

(7)列表和數組的做為數據成員的序列化

類聲明:

    [XmlType("信息")]

    public class Person

    {

        [XmlAttribute("姓名")]

        public string Name;

        [XmlAttribute("性別")]

        public bool Sex;

        public Person() { }//必須提供無參構造器,否則XmlSerializer將出錯

    }

    public class PersonArray

    {

        public List<Person> Array=new List<Person>();

        public Person Person = new Person();

    }

    class Program

    {

        static void Main(string[] args)

        {

            PersonArray ps = new PersonArray();

            ps.Person = new Person();

            ps.Person.Name = "李志偉";

            ps.Person.Sex = true;

            ps.Array.Add(ps.Person);

            ps.Array.Add(ps.Person);

            ps.Array.Add(ps.Person);

            //使用XML序列化對象

            string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑

            Stream fStream = new FileStream(fileName, FileMode.Create);

            XmlSerializer xmlFormat = new XmlSerializer(typeof(PersonArray));

            xmlFormat.Serialize(fStream, ps);//序列化對象

            fStream.Dispose();//關閉文件

            Console.WriteLine("OK!");

            Console.Read();

        }

    }

序列化生成的XML文件:

<PersonArrayxmlns:xsi="..."xmlns:xsd="...">

  <Array>

    <個人信息姓名="李志偉"性別="true" />

    <個人信息姓名="李志偉"性別="true" />

    <個人信息姓名="李志偉"性別="true" />

  </Array>

  <Person姓名="李志偉"性別="true" />

</PersonArray>

註意:假設這裡需要為Array和Person的節點重命名,代碼如下:

    [XmlType("信息")]

    public class Person

    {

        [XmlAttribute("姓名")]

        public string Name;

        [XmlAttribute("性別")]

        public bool Sex;

        public Person() { }//必須提供無參構造器,否則XmlSerializer將出錯

    }

    public class PersonArray

    {

        [XmlArrayItem("個人信息")]

        [XmlArray("人員信息")]

        public List<Person> Array=new List<Person>();

        public Person Person = new Person();

    }

序列化生成的XML文件:

<PersonArrayxmlns:xsi="..."xmlns:xsd="...">

  <人員信息>

    <個人信息姓名="李志偉"性別="true" />

    <個人信息姓名="李志偉"性別="true" />

    <個人信息姓名="李志偉"性別="true" />

  </人員信息>

  <Person姓名="李志偉"性別="true" />

</PersonArray>

註意:把“人員信息”節點去掉呢(直接出現“個人信息”節點)

    [XmlType("信息")]

    public class Person

    {

        [XmlAttribute("姓名")]

        public string Name;

        [XmlAttribute("性別")]

        public bool Sex;

        public Person() { }//必須提供無參構造器,否則XmlSerializer將出錯

    }

    public class PersonArray

    {

        [XmlElement("個人信息")]

        public List<Person> Array=new List<Person>();

        public Person Person = new Person();

    }

序列化生成的XML文件:

<PersonArrayxmlns:xsi="..."xmlns:xsd="...">

  <個人信息姓名="李志偉"性別="true" />

  <個人信息姓名="李志偉"性別="true" />

  <個人信息姓名="李志偉"性別="true" />

  <Person姓名="李志偉"性別="true" />

</PersonArray>

(8)類型繼承與反序列化

類聲明:

    public class Base { }

    [XmlType("信息A")]

    public class PersonA : Base

    {

        [XmlAttribute("姓名")]

        public string Name;

        [XmlAttribute("性別")]

        public bool Sex;

        public PersonA() { }//必須提供無參構造器,否則XmlSerializer將出錯

    }

    [XmlType("信息B")]

    public class PersonB : Base

    {

        [XmlElement("姓名")]

        public string Name;

        [XmlElement("年齡")]

        public int Age;

        public PersonB() { }//必須提供無參構造器,否則XmlSerializer將出錯

    }

    [XmlType("人員信息")]

    public class PersonArray

    {

        [XmlArrayItem(typeof(PersonA)), XmlArrayItem(typeof(PersonB))]

        public List<Base> ListPerson=new List<Base>();

    }

    class Program

    {

        static void Main(string[] args)

        {

            PersonA pa = new PersonA();

            pa.Name = "李志偉A";

            pa.Sex = true;

            PersonB pb = new PersonB();

            pb.Name = "李志偉B";

            pb.Age = 21;

            PersonArray ps = new PersonArray();

            ps.ListPerson.Add(pa);

            ps.ListPerson.Add(pa);

            ps.ListPerson.Add(pb);

            ps.ListPerson.Add(pb);

            //使用XML序列化對象

            string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑

            Stream fStream = new FileStream(fileName, FileMode.Create);

            XmlSerializer xmlFormat = new XmlSerializer(typeof(PersonArray));

            xmlFormat.Serialize(fStream, ps);//序列化對象

            fStream.Dispose();//關閉文件

            Console.WriteLine("OK!");

            Console.Read();

        }

    }

序列化生成的XML文件:

<人員信息xmlns:xsi="..."xmlns:xsd="...">

  <ListPerson>

    <信息A姓名="李志偉A"性別="true" />

    <信息A姓名="李志偉A"性別="true" />

    <信息B>

      <姓名>李志偉B</姓名>

      <年齡>21</年齡>

    </信息B>

    <信息B>

      <姓名>李志偉B</姓名>

      <年齡>21</年齡>

    </信息B>

  </ListPerson>

</人員信息>

註意:同時為列表成員指定多個[XmlArrayItem(typeof(XXX))]可實現多種派生類型混在一起輸出。

(9)排除不需要序列化的成員

類聲明:

    public class Person

    {

        public string Name;

        [XmlIgnore]// 這個屬性將不會參與序列化

        public bool Sex;

        public Person() { }

    }

序列化生成的XML文件:

<Personxmlns:xsi="..."xmlns:xsd="...">

  <Name>李志偉</Name>

</Person>

(10)強制指定成員的序列化順序

類聲明:

    public class Person

    {

        [XmlElement(Order = 2)]

        public string Name;

        [XmlElement(Order = 1)]

        public bool Sex;

        public Person() { }//必須提供無參構造器,否則XmlSerializer將出錯

    }

序列化生成的XML文件:

<Personxmlns:xsi="..."xmlns:xsd="...">

  <Sex>true</Sex>

  <Name>李志偉</Name>

</Person>

(11)自定義序列化行為

類聲明:

    public class Person : IXmlSerializable

    {

        public string Name;

        public bool Sex;

        public Person() { }//必須提供無參構造器,否則XmlSerializer將出錯

        public System.Xml.Schema.XmlSchema GetSchema()

        {

            return null;

        }

        public void ReadXml(System.Xml.XmlReader reader)

        {

            Name = reader.GetAttribute("姓名");

            Sex = reader.GetAttribute("性別").Equals("男") ? true : false;

        }

        public void WriteXml(System.Xml.XmlWriter writer)

        {

            writer.WriteAttributeString("姓名", Name);

            writer.WriteAttributeString("性別", Sex ? "男" : "女");

        }

    }

序列化生成的XML文件:

<Person姓名="李志偉"性別="男" />

(12)序列化設置XML命名空間

類聲明:

    [XmlRoot(Namespace = "http://msdn.microsoft.com/vsdh.xsd")]

    public class Person

    {

        public string Name;

        public bool Sex;

        public Person() { }

    }

序列化生成的XML文件:

<Personxmlns:xsi="..."xmlns:xsd="..."xmlns="http://msdn.microsoft.com/vsdh.xsd">

  <Name>李志偉A</Name>

  <Sex>true</Sex>

</Person>

(13)XML的使用建議

在服務端,C#代碼中:

1. 建議不用使用低級別的XML API來使用XML,除非你是在設計框架或者通用類庫。

2. 建議使用序列化、反序列化的方法來生成或者讀取XML

3. 當需要考慮使用XML時,先不要想著XML結構,先應該定義好數據類型。

4. 列表節點不要使用[XmlElement],它會讓所有子節點【升級】,顯得結構混亂。

5. 如果希望序列化的XML長度小一點,可以採用[XmlAttribute],或者指定一個更短小的別名。

6. 不要在一個列表中輸出不同的數據類型,這樣的XML結構的可讀性不好。

7. 儘量使用UTF-8編碼,不要使用GB2312編碼。

在客戶端,JavaScript代碼中,我不建議使用XML,而是建議使用JSON來代替XML,因為:

1. XML文本的長度比JSON要長,會占用更多的網路傳輸時間(畢竟數據保存在服務端,所以傳輸是免不了的)。

2. 在JavaScritp中使用XML比較麻煩(還有瀏覽器的相容問題),反而各種瀏覽器對JSON有非常好的支持。

(14)反序列化的使用總結

如果XML是由類型序列化得到那的,那麼反序列化的調用代碼是很簡單的,反之,如果要面對一個沒有類型的XML,就需要我們先設計一個(或者一些)類型出來,這是一個逆向推導的過程,請參考以下步驟:

1. 首先要分析整個XML結構,定義與之匹配的類型,

2. 如果XML結構有嵌套層次,則需要定義多個類型與之匹配,

3. 定義具體類型(一個層級下的XML結構)時,請參考以下表格。

XML形式

處理方法

補充說明

XmlElement

定義一個屬性

屬性名與節點名字匹配

XmlAttribute

[XmlAttribute] 加到屬性上

InnerText

[InnerText] 加到屬性上

一個類型只能使用一次

節點重命名

根節點:[XmlType("testClass")] 
元素節點:[XmlElement("name")] 
屬性節點:[XmlAttribute("id")] 
列表子元素節點:[XmlArrayItem("Detail")] 
列表元素自身:[XmlArray("Items")]

6.自定義序列化(僅適用於二進位與SOAP)

(1)自定義序列化的實現方式

可以通過在對象上實現 ISerializable 介面來自定義序列化過程。這一功能在反序列化後成員變數的值失效時尤其有用,但是需要為變數提供值以重建對象的完整狀態。要實現ISerializable,需要實現 GetObjectData()方法以及一個特殊的構造函數,在反序列化對象時要用到此構造函數。

(2)示常式序

    [Serializable]

    public class Person : ISerializable

    {

        public string Name;

        public bool Sex;

        public Person() { }

        //必須的夠著方法,反序列化時調用

        protected Person(SerializationInfo info, StreamingContext context)

        {

            Name = info.GetString("姓名");

            Sex = info.GetBoolean("性別");

        }

        //序列化時調用

        public void GetObjectData(SerializationInfo info, StreamingContext context)

        {

            info.AddValue("姓名", Name + "(自定義序列化)");

            info.AddValue("性別", Sex);

        }

        public override string ToString()

        {

            return "姓名:" + this.Name + "\t性別:" + (this.Sex ? "男" : "女");

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            Person p = new Person();

            p.Name = "李志偉A";

            p.Sex = true;

            //使用二進位序列化對象

            string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑

            Stream fStream = new FileStream(fileName, FileMode.Create);

            BinaryFormatter binFormat = new BinaryFormatter();//創建二進位序列化器

            binFormat.Serialize(fStream, p);//序列化對象

            //使用二進位反序列化對象

            fStream.Position = 0;//重置流位置

            p = (Person)binFormat.Deserialize(fStream);//反序列化對象

            Console.WriteLine(p);

            fStream.Dispose();//關閉文件

            Console.WriteLine("OK!");

            Console.Read();

        }

    }

註意:在序列化過程中調用 GetObjectData()時,需要填充方法調用中提供的SerializationInfo對象。只需按名稱/值對的形式添加將要序列化的變數。其名稱可以是任何文本。只要已序列化的數據足以在反序列化過程中還原對象,便可以自由選擇添加至SerializationInfo 的成員變數。如果基對象實現了 ISerializable,則派生類應調用其基對象的 GetObjectData()方法。同樣,在反序列化時也會調用含有(SerializationInfo info, StreamingContextcontext)參數的特殊的夠著方法!否者將無法反序列化!!!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文版權歸博客園和作者本人共同所有,轉載和爬蟲請註明本系列分享地址:http://www.cnblogs.com/tdws/p/5815735.html 上一篇文章的不合理之處,已經有所修改。 今天分享的是Hash散列數據類型操作,不過我也覺得有了前兩篇的基礎搭建後,你就能自己按照StackExch ...
  • Asp.Net MVC5+ EntityFramework6.0 db first + Autofac(IOC) + SqlServer2014還請大家多多指教啦 anneke.cn ...
  • 前戲:針對上一篇列出來的功能點,今天和大家分享下這個自定義的公式是怎麼設計的,由於我的第一篇博客在首頁被管理員移走了,大家可以點擊這裡來跳轉,看下第一篇的目錄結構。本人作為老菜鳥,和大家分享的也是一些老菜鳥的想法,大神千萬別噴我. 設計背景:當初為什麼要設計這個自定義的計算公式呢,原因就是,這個價格 ...
  • ASP.NET Core開發Docker部署,.NET Core支持Docker 部署運行。我們將ASP.NET Core 部署在Docker 上運行。 大家可能都見識過Docker ,今天我們就詳細瞭解一下Docker的用途,以及真實的應用場景。 Docker源於PaaS,PaaS的應用場景即是D ...
  • 從淘寶UWP第一版發佈到現在,已經有十個月了,期間收到了用戶各種各樣的反饋,感謝這些用戶的反饋,指導我們不斷的修正、完善應用。但是也有一部分需求或建議,由於資源或技術的限制,目前確實無法做到,只能對廣大Win10er說聲抱歉了。下麵針對幾種用戶常提到的反饋做下說明。 最經常的反饋是為什麼在某某版本上 ...
  • 序列 延遲查詢執行 查詢操作符 查詢表達式 表達式樹 (一) 序列 先上一段代碼, 這段代碼使用擴展方法實現下麵的要求: 取進程列表,進行過濾(取大於10M的進程) 列表進行排序(按記憶體占用) 只保留列表中指定的信息(ID,進程名) 為了能清楚理解上面代碼的內部動作,我們需要介紹幾組概念. 1. I ...
  • 模塊是平臺功能的單元,是源碼和數據的集合體。模塊管理(菜單、動作、數據)是整個平臺中框架功能體現的核心。整個平臺內的各個功能模塊都是在此進行配置的。 ...
  • 1. 條件運算符(?:)根據Boolean表達式的值返回兩個值之一。表達式如下: condition ? first_expression : second_expression 2. $""替代String.Format()方法,""中包含字元,有變數的需要用{}括起: 舉例 if (bonus= ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...