《ASP.NET本质论》视图状态 ViewState

                序列化和反序列化
                   对象在内存中以引用的方式相互联结,构成一个复杂的对象数。但是,在外部的设备中,却是以一定的序列保存的,比如,图片文件是以一个有规律的字节序列进行保存的,文本文件是通过字符序列进行保存。所以,内存中的对象如果需要保存到使用序列方式存储的设备在,必须要进行信息的重组,以序列的方式进行描述,才能完成这个任务。这个工作就称为序列化。
                  反序列化就是从序列中重新构建内存中对象的过程。
                  例如,下面定义的是一个Person类。

 [Serializable]
    public class Person
    {
        public int Age { get; private set; }
        public string Name { get; private set; }
        public Person(string name, int age)
        {
            this.Name = name;
            this.Age = age;
        }
    }

当我们创建一个Person类哦对象实例alice之后,在内存中将会有如下的存储结构:
Person alice = new Person("alice", 20);

对象在内存中的表示形式如图所示:

             在C++中,程序员需要参与到序列化和反序列的过程中,在 .NET 中,通过反射,已经可以不再需要程序员参与,非常简单地实现对象的序列化和反序列化。
             在System.Runtime.Serialization 命名空间中,定义了 .NET 中进行序列化和反序列所需要的类和接口。其中接口IFormatter定义了序列化器。
          
                       public interface IFormatter

            主要方法Serialize完成对象的序列化工作,将对象序列化之后写入到流中。
              
               
public void Serialize (
	Stream serializationStream,
	Object graph
)

          Deserialize从流中获取信息,还原为内存中的对象。
               
public Object Deserialize (
	Stream serializationStream
)

           在.NET类库中,命名空间 System.Runtime.Serialization.Formatters.Binary 提供了一个二进制的序列化器 Binary。
[ComVisibleAttribute(true)] 
public sealed class BinaryFormatter : IRemotingFormatter, IFormatter

        使用BinaryFormatter可以非常方便地将alice对象序列化为一个字节序列。
        在序列化的方法中,需要提供一个字节流以保持序列化的结果。为了方便,这里使用MemoryStream将序列化的结果保存在内存中以便使用。
Person alice = new Person("alice", 20);

            BinaryFormatter formatter = new BinaryFormatter();
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            formatter.Serialize(ms, alice);

            byte[] content = ms.ToArray();
            Response.Write(BitConverter.ToString(content));

      我们可以将这些字节通过一个用于读取字节流提供基于流的访问,然后借助于反序列化方法重新在内存中构建一个新的Person对象,这个对象显然不是原来的Person对象,但是,表示的数据都是相同的,所以,从数据的角度来说,我们可以认为还原了原来的对象。
            
System.IO.MemoryStream ms2 = new System.IO.MemoryStream(content);
            Person alice2 = formatter.Deserialize(ms2) as Person;
            
            Response.Write("<br/>"+alice2.Name+"<br/>"+alice2.Age);




         序列化控制
               刚才我们将对象序列化为二进制表示形式,这样的序列化被称为二进制序列化。那么,是不是任何对象都可以进行二进制序列化呢?如果不是的话,什么样的类可以被这样进行二进制序列化呢?
              注意,上面定义的Person类,被标注了一个表情。
                           [Serializable]
             这个标签的定义如下(在使用中,后缀Attribute可以省略)。

public abstract class Attribute : _Attribute
             在使用二进制序列化器的时候,当一个类应用了这个标签,表示这个类的对象实例可以被序列化,如果没有被标记为可序列化,那么,在使用BinaryFormatter进行序列化的时候,CLR将会抛出一个序列化的异常 SerializationException。
            这个标签也可以被应用在类的成员上,不过,在默认情况下,类中的素有私有和共有的成员在序列化的过程中都将被序列化。也就是说,对于支持序列化的类来说,默认情况下,成员已经被应用了支持序列化的标签。如果这个类标注这个标签,可以定制这种类型的序列化过程。
public interface ISerializable
{
    void GetObjectData(
        SerializationInfo info,
        StreamingContext context
    );
}

           在.NET 中,所有的值类型都支持序列化。对于类来说,应用Serializable标签的类将支持序列化操作。例如,常见的System.String,List<T> ,Dictionary<TKey,TValue>,ArrayList 等类型都支持序列化操作。
         
 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值