你的位置:首页 > ASP.net教程

[ASP.net教程][.net 面向对象程序设计进阶] 序列化(Serialization)(二) 通过序列化博客园文章学习XML的序列化


[.net 面向对象程序设计进阶] (10) 序列化(Serialization)(二) 通过序列化博客园文章学习

本节导读:

上节我们介绍了二进制流的序列化,本节继续上节内容介绍

读前必备:

A.修饰符        [.net 面向对象编程基础]  (8) 基础中的基础——修饰符 

B.类和类的实例  [.net 面向对象编程基础]  (9) 类和类的实例

C.类的成员        [.net 面向对象编程基础]  (10) 类的成员(字段、属性、方法)

D.数组与集合   [.net 面向对象编程基础]  (17) 数组与集合

E.泛型            [.net 面向对象编程基础]  (18) 泛型

F.LINQ使用    [.net 面向对象编程基础] (20) LINQ使用

1. 关于

   Markup Language)

 

 

 

 

   W3C 的推荐标准

   关于

2.

类:

主要方法:Serialize和Deserialize

下面先来一个简单有意思的

 首先获取获博客园文章,创建文章实体类,如下:

public class MyBlogs{  /// <summary>  /// 获取我的博客园中文章  /// </summary>  /// <returns></returns>  public static List<MyArticle> GetMyArticle(int count)  {    var document = XDocument.Load(      "http://wcf.open.cnblogs.com/blog/u/yubinfeng/posts/1/" + count      );    List<MyArticle> myArticleList = new List<MyArticle>();    var elements = document.Root.Elements();    //在进行这个工作之前,我们先获取我博客中的文章列表    var result = elements.Where(m => m.Name.LocalName == "entry").Select(myArticle => new MyArticle    {      id = Convert.ToInt32(myArticle.Elements().SingleOrDefault(x => x.Name.LocalName == "id").Value),      title = myArticle.Elements().SingleOrDefault(x => x.Name.LocalName == "title").Value,      published = Convert.ToDateTime(myArticle.Elements().SingleOrDefault(x => x.Name.LocalName == "published").Value),      updated = Convert.ToDateTime(myArticle.Elements().SingleOrDefault(x => x.Name.LocalName == "updated").Value),      diggs = Convert.ToInt32(myArticle.Elements().SingleOrDefault(x => x.Name.LocalName == "diggs").Value),      views = Convert.ToInt32(myArticle.Elements().SingleOrDefault(x => x.Name.LocalName == "views").Value),      comments = Convert.ToInt32(myArticle.Elements().SingleOrDefault(x => x.Name.LocalName == "comments").Value),      summary = myArticle.Elements().SingleOrDefault(x => x.Name.LocalName == "summary").Value,      link = myArticle.Elements().SingleOrDefault(x => x.Name.LocalName == "link").Attribute("href").Value,      author = myArticle.Elements().SingleOrDefault(x => x.Name.LocalName == "author").Elements().SingleOrDefault(x => x.Name.LocalName == "name").Value    }).OrderByDescending(m=>m.published);    myArticleList.AddRange(result);    return myArticleList;  }}/// <summary/// 我的博客文章实体类/// </summary>public class MyArticle{  /// <summary>  /// 文章编号  /// </summary>  public int id { get; set; }  /// <summary>  /// 文章标题  /// </summary>  public string title { get; set; }  /// <summary>  /// 文章摘要  /// </summary>  public string summary { get; set; }  /// <summary>  /// 发布时间  /// </summary>  public DateTime published { get; set; }  /// <summary>  /// 最后更新时间  /// </summary>  public DateTime updated { get; set; }  /// <summary>  /// URL地址  /// </summary>  public string link { get; set; }  /// <summary>  /// 推荐数  /// </summary>  public int diggs { get; set; }  /// <summary>  /// 浏览量  /// </summary>  public int views { get; set; }  /// <summary>  /// 评论数  /// </summary>  public int comments { get; set; }  /// <summary>  /// 作者  /// </summary>  public string author { get; set; }}

下面实现myArticleList对象序列化 

////类://主要方法:Serialize和Deserialize//博客数据的对象化(反序列化)及序列化//(1)获取我博客园中最后10篇文章 (实际上这个过程也是反序列化)List<MyArticle> myArticleList = MyBlogs.GetMyArticle(10);  //(2)将上面的对象myArticleList序列化string  String.Empty;using (MemoryStream ms = new MemoryStream()){          = new typeof(List<MyArticle>));  byte[] arr = ms.ToArray();  = Encoding.UTF8.GetString(arr, 0, arr.Length);  ms.Close();}Console.WriteLine(

运行结果如下:

 

上面的示例,实现了一个最基本的从对象到

3.

我们将上面序列化的文本 

//下面我们刚才输出的using (StringReader sr = new StringReader(=new typeof(List<MyArticle>));          ;  List<MyArticle> myNewArticleList= as List<MyArticle>;  //遍历输出反序化的新对象myNewArticleList  myNewArticleList.ForEach(m =>    Console.WriteLine("文章编号:" + m.id + "\n文章标题:" + m.title)            );  sr.Close();}

运行结果如下:

  

上面的示例实现了从对象的过程。

学会了上面的两个示例,就掌握了

4.

(1)要序列化的类必须有默认的构造的构造函数,才能使用

(2)索引器、私有字段或只读属性(只读集合属性除外)不能被序列化;

(3)不想序列化时:当不想序列化一个属性时,使用[System.

(4)方法不能被序列化(虽然是废话,但是还是列举出来);

(5)枚举变量可序列化为字符串,无需用[

(6)导出非基本类型对象,都必须用[

(7)Attribute中的IsNullable参数若等于false,表示若元素为null则不显示该元素。(针对值类型有效)

(8)某些类就是无法

比如:

IDictionary(如HashTable);

父类对象赋予子类对象值的情况;

对象间循环引用;

(9)对于无法

使用自定义

实现IDictionary的类,可考虑(1)用其它集合类替代;(2)用类封装之,并提供Add和this函数;

某些类型需要先经过转换,然后才能序列化为 

过于复杂的对象用

(10)默认构造函数是必须的,因为反序列化本质上使用的是反射,需要默认构造函数来实例化类,如果去掉其中的默认构造函数,则编译没有问题,但运行就会报错。

尽量不要将比较大的属性放在默认构造函数初始化,那会导致在反序列化时对列表初始化两次:默认构造函数中执行一次,反序列化时从

以上十点注意,其中前三点,也就是加黑的这几点,是重点要知道的。

5. 改变

5.1 更改或删除

使用 

我们对上面最重得到的对象List<MyArticle>进行

//更新默认命名空间//使用System.new //获取文章列表对象List<MyArticle> newArticleList = MyBlogs.GetMyArticle(10);//更改命名空间,并输出string new String.Empty;"MyBlogURL", @"http://www.cnblogs.com/yubinfeng");using (MemoryStream ms = new MemoryStream()){  = new typeof(List<MyArticle>));  byte[] arr = ms.ToArray();  new= Encoding.UTF8.GetString(arr, 0, arr.Length);  ms.Close();}Console.WriteLine(new

我们可以和前面默认的输出结果比较,如下图:

 

也是可以删除命名空间的

System.new "","");

当加入一个空的命名空间时,就可以删除默认的

5.2  更改

我们先列出

更多设置属性如下:

成员

说明

CloseOutput

获取或设置一个值,该值指示在调用 Close 方法时,是否还应该关闭基础流或 TextWriter。

Encoding

获取或设置要使用的文本编码的类型。

Indent

获取或设置一个值,该值指示是否缩进元素。

IndentChars

获取或设置缩进时要使用的字符串。

NamespaceHandling

获取或设置一个值,该值指示在编写 内容时,是否应移除重复的命名空间声明。 的默认是输出程序中出现的所有命名空间声明。

NewLineChars

获取或设置要用于分行符的字符串

NewLineHandling

获取或设置一个值,该值指示是否将输出中的分行符正常化。

NewLineOnAttributes

获取或设置一个值,该值指示是否将属性写入新行。

Omit

获取或设置一个值指示省略 声明。

Encoding

获取或设置要使用的文本编码的类型。

Reset方法

重置以上属性

    API官方地址:http://msdn.microsoft.com/zh-cn/library/system.

   下面我们通过示例。来设置三个属性:去掉声明,换行缩进,指定字符缩进,示例如下:

先定义一个方法

/// <summary>/// 设置三个属性:去掉/// </summary>/// <param name="Obj"></param>/// <returns></returns>public static string ObjectTo= new System.= true;//去除  settings.Encoding = Encoding.Default;//使用默认编码  settings.IndentChars = "--"; //使用指定字符缩进  settings.Indent = true; //换行缩进  System.IO.MemoryStream mem = new MemoryStream();  using (System. System.//去除默认命名空间    new "", "");    = new return Encoding.Default.GetString(mem.ToArray());}

    调用如下:

//使用 设置 //所在命名空间:System.//设置三个属性:去掉Console.WriteLine(ObjectTo

输出结果和之前进行对比,如下图:

 

6. 本节要点:

(1)了解的序列化,将对象转为数据格式

(2)了解的反序列化,将文本转换为对象

(3)了解序更化的注意事项,主要有以下几点:

  • 默认类和无参数构造函数类才可以序列化;
  • 索引器、私有字段或只读属性(只读集合属性除外)不能被序列化
  • 有一些序列化的标记当不想序列化一个属性时,使用[System.标记,能用于属性;
  • [NonSerializable]应用于属性无效,能用于类,结构体等。

(4)改变

使用 

使用 的明名、缩进等元素。 

     下节我们将对通过实现序列化接口I来介绍序列化以及介绍的其他特性,并举例说明序列化的高级应用。