C#笔记15:序列化
本章概要:
1:为什么需要序列化
2:序列化的几种形式
3:关于XML序列化,多说一点
3.1:IDeserializationCallback 接口
4:JSON是什么
4.1提供一段有用的JSON代码
1:为什么需要序列化
序列化是将对象转换为字节流以将其保存在内存、数据库或文件中的过程。其主要目的是保存对象的状态,以便可以在需要时重新创建对象。相反的过程称为反序列化。
此图显示序列化的整个过程。
对象被序列化为流。流传递的不仅是数据,还包括有关对象类型的信息,如对象的版本、区域性和程序集名称。通过该流,可以将对象存储在数据库、文件或内存中。
通过序列化,开发人员还可以执行类似如下的操作:通过 Web 服务将对象发送到远程应用程序、将对象从一个域传递到另一个域、以 XML 字符串的形式跨防火墙传递对象,或者跨应用程序维护安全信息或用户特定信息。
2:序列化的几种格式
序列化对象的时候,有三种格式:二进制、XML、SOAP。
二进制序列化使用二进制编码来生成精简的序列化,以用于存储或基于套接字的网络流等。二进制格式对于大多数 Windows 应用程序均适用。
XML 序列化将对象的公共字段和属性或者方法的参数及返回值序列化为符合特定 XML 架构定义语言 (XSD) 文档的 XML 流。XML 序列化会生成具有转换为 XML 的公共属性和字段的强类型类。
XML 序列化还可用于将对象序列化为符合 SOAP 规范的 XML 流。对于 Web 应用程序或 Web 服务,SOAP 格式对象可以用于你像使用其它语言环境编写的应用程序接口。
3:关于序列化,多说一点
3.1:XML序列化单个类
以下的代码演示了如何将对象写入XML文件,以及将XML文件直接读取为对象:
public class Book { public String title; } public void WriteXML() { Book overview = new Book(); overview.title = "Serialization Overview"; System.Xml.Serialization.XmlSerializer writer = new System.Xml.Serialization.XmlSerializer(typeof(Book)); System.IO.StreamWriter file = new System.IO.StreamWriter( @"c:\temp\SerializationOverview.xml"); writer.Serialize(file, overview); file.Close(); } public void ReadXML() { System.Xml.Serialization.XmlSerializer reader = new System.Xml.Serialization.XmlSerializer(typeof(Book)); System.IO.StreamReader file = new System.IO.StreamReader( @"c:\temp\SerializationOverview.xml"); Book overview = new Book(); overview = (Book)reader.Deserialize(file); Console.WriteLine(overview.title); }
3.2:ArrayList序列化
ArrayList是可以被序列化的集合类,如下使用:
ArrayList dept = new ArrayList(); Student[] list = new Student[]{ new Student(){Age=1}, new Student(){Age=2}}; dept.AddRange(list); SoapFormatter formatter = new SoapFormatter(); MemoryStream stream = new MemoryStream(); formatter.Serialize(stream, dept);
3.3:IDeserializationCallback 接口
指示在完成整个对象图形的反序列化时通知类。
实现当前接口,以作为对在完成对象图形反序列化时所调用的方法的部分支持。
如果一个对象需要在其子对象上执行代码,它可以延迟此操作,实现 IDeserializationCallback,然后仅在此接口上回调代码才执行该代码。
using System; using System.IO; using System.Collections; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization; // This class is serializable and will have its OnDeserialization method // called after each instance of this class is deserialized. [Serializable] class Circle : IDeserializationCallback { Double m_radius; // To reduce the size of the serialization stream, the field below is // not serialized. This field is calculated when an object is constructed // or after an instance of this class is deserialized. [NonSerialized] public Double m_area; public Circle(Double radius) { m_radius = radius; m_area = Math.PI * radius * radius; } void IDeserializationCallback.OnDeserialization(Object sender) { // After being deserialized, initialize the m_area field // using the deserialized m_radius value. m_area = Math.PI * m_radius * m_radius; } public override String ToString() { return String.Format("radius={0}, area={1}", m_radius, m_area); } } class Class1 { [STAThread] static void Main(string[] args) { Serialize(); Deserialize(); } static void Serialize() { Circle c = new Circle(10); Console.WriteLine("Object being serialized: " + c.ToString()); // To serialize the Circle, you must first open a stream for // writing. Use a file stream here. FileStream fs = new FileStream("DataFile.dat", FileMode.Create); // Construct a BinaryFormatter and use it // to serialize the data to the stream. BinaryFormatter formatter = new BinaryFormatter(); try { formatter.Serialize(fs, c); } catch (SerializationException e) { Console.WriteLine("Failed to serialize. Reason: " + e.Message); throw; } finally { fs.Close(); } } static void Deserialize() { // Declare the Circle reference. Circle c = null; // Open the file containing the data that you want to deserialize. FileStream fs = new FileStream("DataFile.dat", FileMode.Open); try { BinaryFormatter formatter = new BinaryFormatter(); // Deserialize the Circle from the file and // assign the reference to the local variable. c = (Circle) formatter.Deserialize(fs); } catch (SerializationException e) { Console.WriteLine("Failed to deserialize. Reason: " + e.Message); throw; } finally { fs.Close(); } // To prove that the Circle deserialized correctly, display its area. Console.WriteLine("Object being deserialized: " + c.ToString()); } }
4:JSON是什么
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集。说到底,JSON跟XML一样,也是保持对象数据的一种方式。
JSON与XML的比较:
◆可读性
JSON和XML的可读性可谓不相上下,一边是简易的语法,一边是规范的标签形式,很难分出胜负。
◆可扩展性
XML天生有很好的扩展性,JSON当然也有,没有什么是XML能扩展,JSON不能的。不过JSON在Javascript主场作战,可以存储Javascript复合对象,有着xml不可比拟的优势。
◆编码难度
XML有丰富的编码工具,比如Dom4j、JDom等,JSON也有提供的工具。无工具的情况下,相信熟练的开发人员一样能很快的写出想要的xml文档和JSON字符串,不过,xml文档要多很多结构上的字符。
4.1提供一段有用的JSON代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web.Script.Serialization;
using System.Runtime.Serialization.Json;
namespace MvcApplication5.AppCode
{
publicclass Class1
{
publicstatic T JSONToObject<T>(string json)
{
T obj = Activator.CreateInstance<T>();
using (MemoryStream stream =new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
DataContractJsonSerializer serializer =new DataContractJsonSerializer(obj.GetType());
return (T)serializer.ReadObject(stream);
}
}
publicstaticstring ObjectToJSON<T> (T t)
{
DataContractJsonSerializer serializer =new DataContractJsonSerializer(t.GetType());
using (MemoryStream stream =new MemoryStream())
{
serializer.WriteObject(stream, t);
return Encoding.UTF8.GetString(stream.ToArray());
}
}
}
}
练习:
1:You create a class library that contains the class hierarchy defined in the following code segment. (Line
numbers are included for reference only.)
1 public class Group{ 2 public Employee[] Employees; 3 } 4 public class Employee{ 5 public string Name; 6 } 7 public class Manager : Employee{ 8 public int Level; 9 }
You create an instance of the Group class. You populate the fields of the instance. When you attempt to serialize
the instance by using the Serialize method of the XmlSerializer class, you receive InvalidOperationException. You
also receive the following error messagE. "There was an error generating the XML document." You need to
modify the code segment so that you can successfully serialize instances of the Group class by using the
XmlSerializer class. You also need to ensure that the XML output contains an element for all public fields in the
class hierarchy. What should you do?
A. Insert the following code between lines 1 and 2 of the code segment:
[XmlArrayItem(Type = typeof(Employee))]
[XmlArrayItem(Type = typeof(Manager))]
B. Insert the following code between lines 1 and 2 of the code segment:
[XmlElement(Type = typeof(Employees))]
C. Insert the following code between lines 1 and 2 of the code segment:
[XmlArray(ElementName="Employees")]
D. Insert the following code between lines 3 and 4 of the code segment:
[XmlElement(Type = typeof(Employee))]
andInsert the following code between lines 6 and 7 of the code segment:
[XmlElement(Type = typeof(Manager))]
Answer: A
2.You are defining a class named MyClass that contains several child objects. MyClass contains a method named
ProcessChildren that performs actions on the child objects. MyClass objects will be serializable. You need to
ensure that the ProcessChildren method is executed after the MyClass object and all its child objects are
reconstructed. Which two actions should you perform? (Each correct answer presents part of the solution.
Choose two.)
A. Apply the OnDeserializing attribute to the ProcessChildren method.
B. Specify that MyClass implements the IDeserializationCallback interface.
C. Specify that MyClass inherits from the ObjectManager class.
D. Apply the OnSerialized attribute to the ProcessChildren method.
E. Create a GetObjectData method that calls ProcessChildren.
F. Create an OnDeserialization method that calls ProcessChildren.
Answer: B, F
3.You are writing an application that uses SOAP to exchange data with other applications. You use a Department
class that inherits from ArrayList to send objects to another application. The Department object is named dept.
You need to ensure that the application serializes the Department object for transport by using SOAP. Which code
should you use?
A. SoapFormatter formatter = new SoapFormatter();
byte[] buffer = new byte[dept.Capacity];
MemoryStream stream = new MemoryStream(buffer);
foreach (object o in dept) { formatter.Serialize(stream, o);}
B. SoapFormatter formatter = new SoapFormatter();
byte[] buffer = new byte[dept.Capacity];
MemoryStream stream = new MemoryStream(buffer);
formatter.Serialize(stream, dept);
C. SoapFormatter formatter = new SoapFormatter();
MemoryStream stream = new MemoryStream();
foreach (object o in dept) { formatter.Serialize(stream, o);}
D. SoapFormatter formatter = new SoapFormatter();
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, dept);
Answer: D
4.You are testing a component that serializes the Meeting class instances so that they can be saved to the file
system. The Meeting class has the following definition:
public class Meeting {
private string title;
public int roomNumber;
public string[] invitees;
public Meeting(){
}
public Meeting(string t){
title = t;
}
}
The component contains a procedure with the following code segment.
Meeting myMeeting = new Meeting("Goals");
myMeeting.roomNumber=1100;
string[] attendees = new string[2]{"John", "Mary"};
myMeeting.invitees = attendees;
XmlSerializer xs = new XmlSerializer(typeof(Meeting));
StreamWriter writer = new StreamWriter(@"C:\Meeting.xml");
xs.Serialize(writer, myMeeting);
writer.Close();
You need to identify the XML block that is written to the C. \Meeting.xml file as a result of running this procedure.
Which XML block represents the content that will be written to the C. \Meeting.xml file?
A. <?xml version="1.0" encoding="utf-8"?>
<Meeting xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<title>Goals</title>
<roomNumber>1100</roomNumber>
<invitee>John</invitee>
<invitee>Mary</invitee>
</Meeting>
B. <?xml version="1.0" encoding="utf-8"?>
<Meeting xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<roomNumber>1100</roomNumber>
<invitees>
<string>John</string>
<string>Mary</string>
</invitees>
</Meeting>
C. <?xml version="1.0" encoding="utf-8"?>
<Meeting xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" title="Goals">
<roomNumber>1100</roomNumber>
<invitees>
<string>John</string>
<string>Mary</string>
</invitees>
</Meeting>
D. <?xml version="1.0" encoding="utf-8"?>
<Meeting xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<roomNumber>1100</roomNumber>
<invitees>
<string>John</string>
</invitees>
<invitees>
<string>Mary</string>
</invitees>
</Meeting>
Answer: B
5.You create a class library that is used by applications in three departments of your company. The library
contains a Department class with the following definition.
public class Department{
public stirng name;
public string manager;
}
Each application uses a custom configuration section to store department-specific values in the application
configuration file as shown in the following code.
<Department>
<name>Hardware</name>
<manager>Amy</manager>
</Dempartment>
You need to write a code segment that creates a Department object instance by using the field values retrieved
from the application configuration file. Which code segment should you use?
A. public class deptElement : ConfigurationElement {
protected override void DeserializeElement(
XmlReader reader, bool serializeCollectionKey)
{Department dept = new Department();
dept.name = ConfigurationManager.AppSettings["name"];
dept.manager =ConfigurationManager.AppSettings["manager"];
return dept; } }
B. public class deptElement: ConfigurationElement {
protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey)
{Department dept = new Department();
dept.name = reader.GetAttribute("name");
dept.manager = reader.GetAttribute("manager"); } }
C. public class deptHandler : IConfigurationSectionHandler {
public object Create(object parent, object configContext,
System.Xml.XmlNode section) {
Department dept = new Department();
dept.name = section.SelectSingleNode("name").InnerText;
dept.manager = section.SelectSingleNode("manager").InnerText;
return dept; } }
D. public class deptHandler : IConfigurationSectionHandler {
public object Create(object parent, object configContext,
System.Xml.XmlNode section) {
Department dept = new Department();
dept.name = section.Attributes["name"].Value;
dept.manager = section.Attributes["manager"].Value;
return dept; } }
Answer: C
6.You are creating a class that performs complex financial calculations. The class contains a method named
GetCurrentRate that retrieves the current interest rate and a variable named currRate that stores the current interest
rate. You write serialized representations of the class. You need to write a code segment that updates the
currRate variable with the current interest rate when an instance of the class is deserialized. Which code segment should you use?
A. [OnSerializing]internal void UpdateValue (StreamingContext context)
{currRate = GetCurrentRate();}
B. [OnSerializing]internal void UpdateValue(SerializationInfo info)
{info.AddValue("currentRate", GetCurrentRate());}
C. [OnDeserializing]internal void UpdateValue(SerializationInfo info)
{info.AddValue("currentRate", GetCurrentRate());}
D. [OnDeserialized]internal void UpdateValue(StreamingContext context)
{currRate = GetCurrentRate();}
Answer: D
7.You need to serialize an object of type List<int> in a binary format. The object is named data. Which code
segment should you use?
A. BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, data);
B. BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
for (int i = 0; i < data.Count; i++) { formatter.Serialize(stream, data[i]);}
C. BinaryFormatter formatter = new BinaryFormatter();
byte[] buffer = new byte[data.Count];
MemoryStream stream = new MemoryStream(buffer, true);
formatter.Serialize(stream, data);
D. BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
data.ForEach(delegate(int num)
{ formatter.Serialize(stream, num); } );
Answer: A
8.You create the definition for a Vehicle class by using the following code segment.
public class Vehicle
{
[XmlAttribute(AttributeName="category")]
public string vehicleType;
public string model;
[XmlIgnore]
public int year;
[XmlElement(ElementName = "mileage")]
public int mile;
public ConditionType condition;
public Vehicle() { }
public enum ConditionType
{
[XmlEnum("Poor")]
BelowAverage,
[XmlEnum("Good")]
Average,
[XmlEnum("Excellent")]
AboveAverage
}
}
You create an instance of the Vehicle class. You populate the public fields of the Vehicle class instance as show n
in the following .
Vehicle v = new Vehicle();
v.vehicleType = "car";
v.model = "race";
v.year = 2002;
v.mile = 15000;
v.condition = Vehicle.ConditionType.AboveAverage;
You need to identify the XML block that is produced when this Vehicle class instance is serialized . Which block of XML represents the output of serializing the Vehicle instance?
A. <?xml version="1.0" encoding="utf-8"?>
<Vehicle xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"" vehicleType="car">
<model>racer</model>
<miles>15000</miles> <condition>AboveAverage</condition>
</Vehicle>
B. <?xml version="1.0" encoding="utf-8"?>
<Vehicle xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" category="car">
<model>racer</model>
<mileage>15000</mileage>
<condition>Excellent</condition>
</Vehicle>
C. <?xml version="1.0" encoding="utf-8"?>
<Vehicle xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" category="car">
<model>racer</model>
<mileage>15000</mileage>
<conditionType>Excellent</conditionType>
</Vehicle>
D. <?xml version="1.0" encoding="utf-8"?>
<Vehicle xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<category>car</category>
<model>racer</model>
<mileage>15000</mileage>
<condition>Excellent</condition>
</Vehicle>
Answer: B
NET C# 入门级 | .NET C# 专业级 | .NET 架构级 | BS系统专业级 | BS系统安全 |
1.开篇及C#程序、解决方案的结构 2.源码管理之TFS入门 3.打老鼠初级 …… 21.CMS之主要功能实现 22.进程和线程基础 23.类型转换 24.算法基础 25.初级课程之剩余知识点 |
1.消灭打老鼠游戏中的自定义委托 2.垃圾回收 3.Dispose模式 …… 16.异常使用指导 17.最常用的重构指导 18.Debug和IDE的进阶 19.Resharper的使用 20.ILSPY的使用 |
1.Socket入门 2.打造打老鼠游戏网络版 3.WCF入门 …… 10.依赖注入 11.万物兼可测试 12.软件指标之覆盖率计算 13.软件指标之代码行 14.软件指标之圈复杂度、嵌套深度 |
1.HTML 2.WebForm原理 3.CSS必知必会 …… 19.让浏览器缓存Shop 20.Asp.net的生命周期 21.Asp.net网站的发布以及调试晋级 22.BS程序的本质 23.压力测试我们的Shop |
1.Fiddler必知必会 2.IE开发者工具必知必会 3.跨站脚本防范 4.权限欺骗防范 5.参数越界防范 6.会话劫持防范 7.CSRF防范 8.盗链防范 9.静态文件的保护 |