序列化(serialization)就是把对象的当前状态(字段及其值)转换数据流,可以把得到的数据流存放到文件、数据库、内存或其它地方;然后在我们需要时,使用反序列化(deserialization)将对象恢复。在.Net中,要序列化一个对象,可以使用属性将类的元素标为可序列化的(Serializable)和不可被序列化的(NonSerialized)。通过SoapFormatter(基于XML)和BinaryFormatter可以得到不同的数据流格式。
一、可序列化(Serializable)和不可序列化(NonSerialized)属性
如果允许一个类序列化,需要在类上标记[Serializeble]属性
[Serializable] //通过标记该属性,说明此类可以被序列化
public class User


{
private int id;
private string name;
[NonSerialized] //标记该属性后,email字段将不会被序列化
private string email;

public User(int id, string name, string email)

{
this.id = id;
this.name = name;
this.email = email;
}
}
如果一个可序列化的类包含了对另一个类的引用,那么被引用的类也必须支持序列化
[Serializable] //通过标记该属性,说明此类可以被序列化
public class User


{
private int id;
private string name;
private Contact contact; //引用了一个类

public User(int id, string name, string email)

{
this.id = id;
this.name = name;
this.email = email;
}
}

[Serializable]
public class Contact


{
private string email;
private string qq;
private string msn
}
二、SoapFormatter和BinaryFormatter
下面的代码分别使用SoapFormatter和BinaryFormatter将User类序列化到文件中:
namespace SerializApp


{
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;
using System.Runtime.Serialization.Formatters.Binary;

class Program

{
static void Main(string[] args)

{
User user = new User(1001, "netflu", "netflu@msn.com");

FileStream mySoap = File.Create(@"C:\Soap_user.txt");
new SoapFormatter().Serialize(mySoap, user);
mySoap.Close();

FileStream myBinary = File.Create(@"C:\Binary_user.dat");
new BinaryFormatter().Serialize(myBinary, user);
myBinary.Close();
}
}

[Serializable]
public class User

{
private int id;
private string name;
[NonSerialized]
private string email;

public User(int id, string name, string email)

{
this.id = id;
this.name = name;
this.email = email;
}
}
}
使用SoapFormatter得到的数据流(Soap_user.txt):
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<a1:User id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/SerializApp/SerializApp%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<id>1001</id>
<name id="ref-3">netflu</name>
</a1:User>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
使用BinaryFormatter得到的数据流(Binary_user.dat):
BSerializApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null SerializApp.User idname ? netflu
通过对SoapFormatter和BinaryFormatter输出的数据流进行观察,可以发现他们各有优缺点,Soap的可读性高,而Binary的数据量小。
三、自定义序列化
如果要精确控制对象的序列化,需要实现ISerializable接口
//ISerializable接口原型
public interface ISerializable

{
void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
}
以下是一个实现了ISerializable接口的类:
[Serializable]
public class User : ISerializable

{
private int id;
private string name;
private string email;

public User(int id, string name, string email)

{
this.id = id;
this.name = name;
this.email = email;
}

private User(SerializationInfo info, StreamingContext context)

{
this.id = info.GetInt32("id");
this.name = info.GetString("name");
this.email = info.GetString("email");
}


ISerializable 成员#region ISerializable 成员

public void GetObjectData(SerializationInfo info, StreamingContext context)

{
info.AddValue("id", id);
info.AddValue("name", name);
info.AddValue("email", email);
}

#endregion
}
主要通过SerializationInfo对象提供的AddValue方法通过键值对来保存一个值,然后通过一系列GetValue方法来取出值。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现