序列化(Serialization)是将对象转换为可存储或传输的格式的过程,以便在需要时可以重新创建对象。反序列化(Deserialization)则是将序列化后的数据重新转换为对象的过程。
为何要序列化和反序列化?
总而言之,序列化和反序列化提供了一种机制,用于将对象转换为可存储或传输的格式,以及从序列化的数据重新创建对象。这种机制在数据持久化、数据传输、对象复制以及跨平台和语言交互等方面都非常有用,是实现持久化、通信和数据交换的关键技术之一。
三种序列化和反序列化方法:
BinaryFormatter
类可以将对象序列化为二进制格式,或将二进制数据反序列化为对象。这种方式非常高效,但生成的二进制数据不可读。XmlSerializer
类可以将对象序列化为可读的 XML 格式,或将 XML 数据反序列化为对象。XML序列化支持公共属性和字段,并且易于与其他平台和语言进行交互。JsonSerializer
类可以将对象序列化为 JSON 格式,或将 JSON 数据反序列化为对象。JSON是一种轻量级的数据交换格式,易于阅读和理解,并且广泛用于Web应用程序和API。某个元素不想被序列化打上标签
1、可以使用[NonSerialized]属性来标志
2、可以使用[XmlIgnore]来标志。
[二进制序列化]
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Program
{
public static void Main()
{
// 创建一个Person对象
Person person = new Person { Name = "Alice", Age = 30 };
// 序列化
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, person);
byte[] serializedData = stream.ToArray();
// 将二进制数据保存到文件或通过网络传输
// ...
Console.WriteLine("Serialized data: " + BitConverter.ToString(serializedData));
}
// 反序列化
using (MemoryStream stream = new MemoryStream(serializedData))
{
Person deserializedPerson = (Person)formatter.Deserialize(stream);
Console.WriteLine("Deserialized person: " + deserializedPerson.Name + ", " + deserializedPerson.Age);
}
}
}
上述示例中,我们定义了一个Person
类,并使用[Serializable]
特性标记为可序列化。
首先,在Main
方法中创建一个Person
对象,设置其属性值。
然后,我们创建一个BinaryFormatter
对象,并使用Serialize
方法将person
对象序列化到内存流中。通过调用ToArray
方法,将内存流中的数据转换为字节数组。
接下来,我们可以将生成的二进制数据保存到文件或通过网络传输。
最后,我们使用另一个内存流(使用序列化的二进制数据进行初始化),并使用Deserialize
方法将二进制数据反序列化为Person
对象。通过强制类型转换,我们可以将反序列化后的对象分配给deserializedPerson
变量,并输出其属性值。
using {}
在C#中,using
语句是一种用于自动管理资源的语法结构。它可以确保在使用完资源后正确地释放、关闭或销毁资源,无论是否发生异常。在using
语句中,resource
是一个实现了IDisposable
接口的对象,通常是需要手动释放的资源,例如文件、数据库连接、网络连接等。
当进入using
语句块时,会自动调用resource
对象的Dispose
方法。这样可以确保资源在使用完后被及时释放,而无需手动调用Dispose
方法。
以下是一个使用using
语句的示例,展示了如何正确使用文件流并确保资源的释放:
using System;
using System.IO;
public class Program
{
public static void Main()
{
// 使用using语句创建文件流并自动管理资源
using (FileStream fileStream = new FileStream("example.txt", FileMode.Create))
{
// 写入数据到文件流
byte[] data = { 72, 101, 108, 108, 111 };
fileStream.Write(data, 0, data.Length);
} // 在此处自动调用fileStream.Dispose()方法,释放资源
// 继续执行其他代码
Console.WriteLine("File write operation completed.");
}
}
在上述示例中,我们使用using
语句创建了一个FileStream
对象并命名为fileStream
。在using
代码块中,我们可以使用fileStream
对象进行文件写入操作。
一旦代码执行完毕或离开using
代码块的范围,会自动调用fileStream.Dispose()
方法,确保文件流资源被释放。
使用using
语句可以简化资源管理的代码,避免手动调用Dispose
方法或忘记释放资源的情况。它是一种推荐的做法,特别是在需要使用需要显式释放的资源时。
[XML序列化]
using System;
using System.IO;
using System.Xml.Serialization;
[Serializable]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Program
{
public static void Main()
{
// 创建一个Person对象
Person person = new Person { Name = "Alice", Age = 30 };
// 序列化到XML
XmlSerializer serializer = new XmlSerializer(typeof(Person));
using (TextWriter writer = new StreamWriter("person.xml"))
{
serializer.Serialize(writer, person);
}
Console.WriteLine("Person object serialized to XML.");
// 反序列化XML到对象
using (TextReader reader = new StreamReader("person.xml"))
{
Person deserializedPerson = (Person)serializer.Deserialize(reader);
Console.WriteLine("Deserialized person: " + deserializedPerson.Name + ", " + deserializedPerson.Age);
}
}
}
在上述示例中,我们定义了一个Person
类,并使用[Serializable]
特性标记为可序列化。
首先,在Main
方法中创建一个Person
对象,设置其属性值。
然后,我们创建了一个XmlSerializer
对象,并使用Serialize
方法将person
对象序列化为XML格式,并将其写入到名为person.xml
的文件中。
接下来,我们使用XmlSerializer
的Deserialize
方法从XML文件中读取数据,并将其反序列化为Person
对象。通过强制类型转换,我们可以将反序列化后的对象分配给deserializedPerson
变量,并输出其属性值。
这个示例演示了使用XML序列化和反序列化的基本用法。通过将对象序列化为XML格式,我们可以将对象保存到文件中,或者在需要时从XML文件中还原对象的状态。请注意,XML序列化对于类和属性需要满足一定的要求,例如需要有公共的无参数构造函数和可序列化的属性。
在实际应用中,还可以使用XML命名空间、属性重命名、序列化选项等进行更高级的配置和处理。
[JSON序列化]
using System;
using System.IO;
using System.Text.Json;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Program
{
public static void Main()
{
// 创建一个Person对象
Person person = new Person { Name = "Alice", Age = 30 };
// 序列化为JSON
string jsonString = JsonSerializer.Serialize(person);
// 将JSON字符串保存到文件或通过网络传输
using (StreamWriter writer = new StreamWriter("person.json"))
{
writer.Write(jsonString);
}
Console.WriteLine("Person object serialized to JSON.");
// 反序列化JSON字符串为对象
string jsonFromFile;
using (StreamReader reader = new StreamReader("person.json"))
{
jsonFromFile = reader.ReadToEnd();
}
Person deserializedPerson = JsonSerializer.Deserialize(jsonFromFile);
Console.WriteLine("Deserialized person: " + deserializedPerson.Name + ", " + deserializedPerson.Age);
}
}
在上述示例中,我们定义了一个Person
类,其中包含Name
和Age
属性。
首先,在Main
方法中创建一个Person
对象,设置其属性值。
然后,我们使用JsonSerializer
类的Serialize
方法将person
对象序列化为JSON字符串。得到的JSON字符串可以保存到文件或通过网络传输。
接下来,我们使用StreamWriter
将JSON字符串写入到名为person.json
的文件中。
然后,我们使用StreamReader
从person.json
文件中读取JSON字符串。
最后,我们使用JsonSerializer
类的Deserialize
方法将JSON字符串反序列化为Person
对象。通过泛型参数,我们指定了要反序列化的对象类型。然后,我们可以访问反序列化后的对象的属性值,并进行输出。
这个示例演示了使用JSON序列化和反序列化的基本用法。通过将对象序列化为JSON字符串,我们可以将对象保存到文件中,或者在需要时从JSON字符串中还原对象的状态。
在实际应用中,还可以使用JsonSerializerOptions
类进行更高级的配置和处理,例如处理日期时间格式、忽略空值属性、自定义命名策略等。
总结起来,序列化和反序列化是将对象转换为可存储或传输的格式以及从序列化的数据重新创建对象的过程。在C#中,可以使用二进制序列化、XML序列化或JSON序列化来实现对象的序列化和反序列化。选择合适的序列化方式取决于具体的需求和场景。