序列化和反序列化(二)--自定义序列化

来源:互联网 发布:商城优化方案 编辑:程序博客网 时间:2024/05/16 08:13

           除了常用的序列化方式,我们也可以自己自定义序列化过程。自定义序列化只需要实现ISerializable接口就可以了,它位于System.Runtime.Serialization命名空间。

          public interface ISerializable{

                void GetObjectData(SerializationInfo info,StreamingContext context)

                 {}

         }

SerialzationInfo有点类似于BinaryWriter和BinaryReader,用于写入和读取对象的属性。它主要包括一组AddValue()方法和一组Get<Type>()方法,还有其他一些属性用于获得程序集和类型信息。StreamingContext则很少用到。

 比如:

 class Program
    {
        static void Main(string[] args)
        {
            SoapFormatter formatter;
            if (File.Exists("D:\\Product.xml"))
            {
                //反序列化
                using (FileStream fs = new FileStream("D:\\Product.xml", FileMode.Open, FileAccess.Read))
                {
                    formatter = new SoapFormatter();
                    Product product = formatter.Deserialize(fs) as Product;
                    Console.WriteLine(product);
                    Console.ReadLine();
                }            
            }
            else
            {

                //序列化
                string connString = "Data Source=.Initial Catalog=DB;User ID=sa;PassWord=123";
                Product item = new Product(connString);
                using (FileStream fs = new FileStream("D:\\Product.xml", FileMode.Create))
                {
                    formatter = new SoapFormatter();
                    formatter.Serialize(fs, item);
                    Console.ReadLine();
                }
            }
        }
    }
    
    [Serializable]
    public class Product : ISerializable 
    {
        private string connString;
        [NonSerialized]
        public SqlConnection conn;
        public Product(string connString)
        {
            this.connString=connString;
        }


        public void GetObjectData(SerializationInfo info,StreamingContext context)
        {
            string encrypted = this.connString.Replace("a", "*").Replace("s","+").Replace("i","$");
            info.AddValue("encrypted", encrypted);
        }

        protected Product(SerializationInfo info, StreamingContext context)
        {
            string encrypted = info.GetString("encrypted");
            this.connString = encrypted.Replace("*","a").Replace("+","s").Replace("$","i");
        }


        public override string ToString()
        {
            return this.connString;
        }
    }

上面两处需要注意:

1) 需要定义一个在反序列化时用于还原属性值的构造函数,并且函数签名的格式必须为:<ClassName>(SerializationInfo info,StreamContext context).在本例子中,将这个构造函数声明为protected,它只有在反序列化时通过反射来调用,将其声明为protected可以避免该构造函数在其他情况下被调用。

2)AddValue(string name,object value)和GetString(string name)中的参数值name必须要保持一致,单不一定与类型的字段或属性名相同。

0 0
原创粉丝点击