当前位置:编程学习 > asp >>

.NET简谈组件程序设计之(渗入序列化过程)

今天这篇文章是来讲解怎么运用一些高级的功能,在序列化、反序列化过程中进行一些控制。

这里穿插一句题外话:其实在我们自己编写组件的时候真的有好多东西可以借鉴.NET平台的一些优点,它的功能都不是死的,可以订阅、可以切入,在我们编写组件的时候,我们其实也要好好考虑一些高级的特性。
上面这段话其实是为了铺垫用的,意思是说序列化组件在它工作的时候我们可以“参合”进去。
IFormatter格式器接口在工作的时候会去检查要序列化的对象是否用Serializable特性进行了标记,如果有,那么就进行深度递归遍历或者广度递归遍历所有成员,如果内部成员被NonSerialized禁止序列化特性标记,那么IFormatter将跳过该成员。在对象的内部所有的成员如果没有被禁止序列化,那么都会经过序列化工程,所以我们很难保证在特殊的对象上能否递归遍历序列化成功。
很典型的对象就是event事件对象,在订阅列表中我们不能保证所有的订阅者都能够被序列化,但是我们又想在反序列化的时候能初始化一些数据。
IDeserializationCallback接口
using System; 
using System.Runtime.InteropServices; 
 
namespace System.Runtime.Serialization 

    // 摘要: 
    //     指示在完成整个对象图形的反序列化时通知类。 
    [ComVisible(true)] 
    public interface IDeserializationCallback 
    { 
        // 摘要: 
        //     在整个对象图形已经反序列化时运行。 
        // 
        // 参数: 
        //   sender: 
        //     开始回调的对象。当前未实现该参数的功能。 
        void OnDeserialization(object sender); 
    } 

IDeserializationCallback接口是反序列化时会执行的接口,接口里面只有一个OnDeserialization方法,系统在反序列化的时候会检查待序列化对象是否实现了IDeserializationCallback接口,如果实现了,那么系统就调用该接口中的OnDeserialization方法。[王清培版权所有,转载请给出署名]
那么这个方法我们有何用呢,我们来看代码;
using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Runtime.Serialization; 
 
namespace ConsoleApplication1.序列化和持久化 

    [Serializable] 
    public class MyClass : IDeserializationCallback 
    { 
        public MyClass() { } 
        public string number = "MyClass状态"; 
 
        [field: NonSerialized]//事件必须用field进行修饰 
        public event EventHandler Event; 
 
 
        #region IDeserializationCallback 成员 
 
        public void OnDeserialization(object sender) 
        { 
 
        } 
 
        #endregion) 
 
        
    } 

MyClass类中有一个Event事件对象,我们在它上面加了禁止序列化特性,前面的field是用来把event对象也当成字段来看待,因为NonSerialized特性只能用在field字段上。
我们实现IDeserializationCallback接口,这个接口的方法会再每次反序列化的时候执行。
using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Formatters.Binary; 
using System.Runtime.Serialization.Formatters.Soap; 
using System.Runtime.Serialization.Formatters; 
using System.IO; 
 
namespace ConsoleApplication1.序列化和持久化 

    public static class Program 
    { 
        public static void Main() 
        { 
            SoapFormatter formatter = new SoapFormatter(); 
            Stream stream = new FileStream("obj.xml", FileMode.Create, FileAccess.Write); 
            using (stream) 
            { 
                MyClass myclass = new MyClass(); 
                myclass.Event += new EventHandler(myclass_Event); 
                formatter.Serialize(stream, myclass); 
            } 
 
            Stream stream1 = new FileStream("obj.xml", FileMode.Open, FileAccess.Read); 
            using (stream1) 
            { 
                MyClass myclass = formatter.Deserialize(stream1) as MyClass; 
            } 
        } 
 
        static void myclass_Event(object sender, EventArgs e) 
        { 
 
        } 
    } 

 
我们在MyClass类中订阅了Event事件,如果我没有在MyClass类中的Event事件上加上禁止序列化特性,那么执行序列化的时候肯定是回报错的。
如果我们需要再对象MyClass存在的时候就需要有一个事件订阅者存在,比如对象内部的日志记录、消息发送等。我们就可以在OnDeserialization方法中进行处理。
using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Runtime.Serialization; 
 
namespace ConsoleApplication1.序列化和持久化 

    [Serializable] 
    public class MyClass : IDeserializationCallback 
    { 
        public MyClass() { } 
        public string number = "MyClass状态"; 
 
        [field: NonSerialized]//事件必须用field进行修饰 
        public event EventHandler Event; 
 
 
        #region IDeserializationCallback 成员 
 
        public void OnDeserialization(object sender) 
        { 
&

补充:Web开发 , ASP.Net ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,