千家信息网

如何理解.Net组件程序设计中的序列化

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,如何理解.Net组件程序设计中的序列化,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。.Net组件程序设计之序列化自动序列化Seriali
千家信息网最后更新 2026年11月02日如何理解.Net组件程序设计中的序列化

如何理解.Net组件程序设计中的序列化,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

.Net组件程序设计之序列化

自动序列化

Serializable属性

 1     [Serializable] 2     public class SerializableCase 3  4     { 5  6         public SerializableCase() { } 7  8         private string _State; 9 10         public string State11 12         {13 14             get { return _State; }15 16             set { _State = value; }17 18         }19 20     }

在上面的示例类型上加上Serializable属性这样将示例类型标记为可序列化类型.

格式化序列化器

二进制格式器
 1     public class MySerializableCase 2     { 3         public static void BinaryFormatterSerialize() 4         { 5             IFormatter formatter = new BinaryFormatter(); 6             Stream stream = new FileStream("jin.glory", FileMode.Create, FileAccess.ReadWrite); 7             using (stream) 8             { 9                 SerializableCase serCase = new SerializableCase();10                 serCase.State = "Test";11                 formatter.Serialize(stream, serCase);12             }13         }14 15         public static void BinaryFormatterDesSerialize()16         {17             Stream stream = new FileStream("jin.glory", FileMode.Open, FileAccess.Read);18             IFormatter formatter = new BinaryFormatter();19             using (stream)20             {21                 SerializableCase serCase = formatter.Deserialize(stream) as SerializableCase;22                 return serCase.State;23             }24         }25     }

BinaryFormattSerialize()方法里只是实例化SerializableCase类型,然后对State属性赋值,代表一个状态。调用 MySerializableCase.BinaryFormattSerialize()后.NET把序列化好的文件流保存到了jin.glory文件中.

图1

文件的名称和后缀格式都是自己随便定义的。然后再调用反序列化,获取到之前序列化的对象状态。

1   string state = MySerializableCase.BinaryFormattDesSerialize();2   Console.WriteLine(state);

图2

SOAP格式器

SoapFormatter是在命名空间System.Runtime.Serialization.Formatters.Soap下的(在System.Runtime.Serialization.Formatters.Soap.dll中)

 1 public class MySerializableCase 2     { 3         public static void SoapFormatterSerialize() 4         { 5             IFormatter formatter = new SoapFormatter(); 6             Stream stream = new FileStream("Soap.xml", FileMode.Create, FileAccess.ReadWrite); 7             using (stream) 8             { 9                 SerializableCase serCase = new SerializableCase();10                 serCase.State = "Test";11                 formatter.Serialize(stream, serCase);12             }13         }14 15         public static string SoapFormatterDesSerialize()16         {17             Stream stream = new FileStream("Soap.xml", FileMode.Open, FileAccess.Read);18             IFormatter formatter = new SoapFormatter();19             using (stream)20             {21                 SerializableCase serCase = formatter.Deserialize(stream) as SerializableCase;22                 return serCase.State;23             }24         }25     }


和上面的二进制格式化器使用的方式近乎相同,唯一不同的是,使用Soap格式化器生成的序列化文件耗时更长,占用空间也比较大,但是它是遵循着SOAP协议的,这在跨平台操作数据间是很有用的,平台只需要解析重建就能把对象重新的生成出来。

不可序列化成员
 1     [Serializable] 2     public class SerializableCase 3     { 4         public SerializableCase() { } 5  6         private string _State; 7  8         public string State 9         {10             get { return _State; }11             set { _State = value; }12         }13 14         [NonSerialized]15         private DonotSerializable _DonotSerializable;16 17         public DonotSerializable DonotSerializable18         {19             get { return _DonotSerializable; }20             set { _DonotSerializable = value; }21         }22     }23     public class DonotSerializable24     {25         public DonotSerializable() { }26 27         public string DonotSerializableData28         {29             get;30             set;31         }32     }

修改了一下第一段的示例代码,增加了个属性,并且设置其字段为NonSerialized,这样在.NET序列化这个类的实例的时候,检测到了[NonSerialized]的时候就会跳过它,因为有的对象确实是不适合序列化来进行持久化的,不过这样的做的也会有个问题,就是对象的状态丢失,就是不可序列化的部分会丢失。看一下下面的代码:

 1     public class MySerializableCase 2     { 3         public static void BinaryFormatterSerialize() 4         { 5             IFormatter formatter = new BinaryFormatter(); 6             Stream stream = new FileStream("jin.glory", FileMode.Create, FileAccess.ReadWrite); 7             using (stream) 8             { 9                 SerializableCase serCase = new SerializableCase();10                 serCase.State = "Test";11                 serCase.DonotSerializable = new DonotSerializable();12                 serCase.DonotSerializable.DonotSerializableData = "DonotSerializableData";13                 formatter.Serialize(stream, serCase);14             }15         }16 17         public static string BinaryFormatterDesSerialize()18         {19             Stream stream = new FileStream("jin.glory", FileMode.Open, FileAccess.Read);20             IFormatter formatter = new BinaryFormatter();21             using (stream)22             {23                 SerializableCase serCase = formatter.Deserialize(stream) as SerializableCase;24                 return serCase.State+"_"+serCase.DonotSerializable.DonotSerializableData;25             }26         }27      }

修改了上面的二进制格式器的代码,调用一下测试代码我们一起来看下结果:

1 MySerializableCase.BinaryFormatterSerialize();2 string state = MySerializableCase.BinaryFormatterDesSerialize();3 Console.WriteLine(state);

图3

在反序列化的时候,对象SerializableCase的DonotSerializable属性丢失了,所以才会报错。
对于这样的情况,.NET提供了IDeserializationCallback接口,它里面只有一个函数void OnDeserialization(object sender),只要实现了IDeserializationCallback,并且在OnDeserialization函数里实现具体的对不可序列化对象的初始化。

 1     [Serializable] 2     public class SerializableCase:IDeserializationCallback 3     { 4         public SerializableCase() { } 5  6         private string _State; 7  8         public string State 9         {10             get { return _State; }11             set { _State = value; }12         }13 14         [NonSerialized]15         private DonotSerializable _DonotSerializable;16 17         public DonotSerializable DonotSerializable18         {19             get { return _DonotSerializable; }20             set { _DonotSerializable = value; }21         }22 23         public void OnDeserialization(object sender)24         {25             _DonotSerializable = new DonotSerializable();26             _DonotSerializable.DonotSerializableData = "DonotSerializableData->Test";27         }28     }

按照上面的调用方式,来看一下结果:

图4

这样是在反序列化的时候,如果检测到了实例类型实现了IDeserializationCallback接口,是在反序列化完成的时候会执行实现了IDeserializationCallback的OnDeserialization()方法,这样可以对一些不可序列化的属性状态在这个方法里来实现。

序列化事件

.NET2.0
引进了对序列化事件的支持,当序列化和反序列化的时候,.NET在你的类上调用指定的方法,.NET中定义了四个序列化和反序列化事件。
serializing事件是在序列化发生之前被触发,
serialized 事件是在序列化之后被触发,
deserializing事件是在反序列化之前被触发,
deserialized事件是在反序列化之后被触发。

引用先前的示例代码SerializableCase类的初始代码:

    [Serializable]    public class SerializableCase //:IDeserializationCallback    {        public SerializableCase() { }        private string _State;        public string State        {            get { return _State; }            set { _State = value; }        }    }

添加了事件后的示例代码是这样的:

 1     [Serializable] 2     public class SerializableCase  3     { 4         public SerializableCase() { } 5         private string _State; 6         public string State 7         { 8             get { return _State; } 9             set { _State = value; }10         }11 12         [OnSerializing]13         private void OnSerializing(StreamingContext context)14         {15             _State = "此时的状态是:序列化之前";16             Console.WriteLine(State);17         }18 19         [OnSerialized]20         private void OnSerialized(StreamingContext context)21         {22             _State = "此时的状态是:序列化之后";23             Console.WriteLine(State);24         }25 26         [OnDeserializing]27         private void OnDeserializing(StreamingContext context)28         {29             _State = "此时的状态是:反序列化之前";30             Console.WriteLine(State);31         }32 33         [OnDeserialized]34         private void OnDeserialized(StreamingContext context)35         {36             _State = "此时的状态是:反序列化之后";37             Console.WriteLine(State);38         }39     }

使用之前定义好的MySerializableCase类型中的静态方法,稍作修改来演示一下,

 1         public static void SoapFormatterSerialize() 2         { 3             IFormatter formatter = new SoapFormatter(); 4             Stream stream = new FileStream("Soap.xml", FileMode.Create, FileAccess.ReadWrite); 5             using (stream) 6             { 7                 SerializableCase serCase = new SerializableCase(); 8                 formatter.Serialize(stream, serCase); 9             }10         }11         public static string SoapFormatterDesSerialize()12         {13             Stream stream = new FileStream("Soap.xml", FileMode.Open, FileAccess.Read);14             IFormatter formatter = new SoapFormatter();15             using (stream)16             {17                 SerializableCase serCase = formatter.Deserialize(stream) as SerializableCase;18                 return serCase.State;19             }20             21         }

测试代码:

1 MySerializableCase.SoapFormatterSerialize();2 MySerializableCase.SoapFormatterDesSerialize();3 Console.ReadLine();

图5

从结果中就很明显的显示出来了,这里要说几句题外话,细心的朋友可能发现了,在SerializableCase类型中的四个事件函数签名都是相同的,这是因为在.NET中为这个这个序列化和反序列化事件定义的委托就是这个签名,在这个类型实例序列化和反序列化的时候会检测到.NET会反射实例内部所有的函数 检测是否有附加了序列化事件,如果判断了有则会继续检查这个函数的签名,如果函数签名也匹配了,就会把这个函数挂上委托。

可以这样指定一个函数为事件指定调用函数:

1 [OnSerializing]2 [OnSerialized]3 [OnDeserializing]4 [OnDeserialized]5 private void OnGenericSerializEventMethod(StreamingContext context)6 {7     ……8 }

看完上述内容,你们掌握如何理解.Net组件程序设计中的序列化的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

序列 事件 函数 代码 状态 类型 方法 时候 是在 格式 对象 属性 实例 示例 面的 文件 检测 程序 程序设计 组件 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技股 保险科技 互联网保险 深圳恒合互联网络科技有限公司 互联网电商科技 科技类互联网 广州凡科互联网科技 猫创互联网科技 海南购全球互联网科技 汉立互联网科技有限公司联系电话 银川新华互联网科技学校地址 成都玖崟互联网科技有限公司乐商圈怎么样 云创客互联网科技公司 贵州叶脉互联网科技有限公司所属行业 福建科技产业互联网发展 2021互联网科技公司排名 广州百诚互联网科技有限公司官网 宁波跨境商互联网科技有限公司 互联网科技新闻 北京天晋互联网科技有限公司 10位科技互联网大佬 互联网科技海报 苏州找大状互联网科技有限公司 中国互联网科技工作委员会毛军 A股互联网金融科技公司 金融科技 互联网金融 互联网科技ppt模板 左右互联网络科技 互联网保险科技创业 雨阳互联网卡科技有限公司 半导体是互联网高科技吗
0