国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

詳解F#對象序列化為XML的實現方法

開發 后端
在這里我們將討論的是F#對象序列化為XML的實現方法,希望對大家用好F#開發有所幫助。

本文將從F#對象開始,詳細描述F#對象序列化為XML的實現方法,期間還與C#進行了對比。希望通過本文,能讓大家更好的理解F#。

#T#

這兩天在用F#寫一小段代碼,需要把一些對象存到外部文件中去。這個功能很容易,因為.NET本身就內置了序列化功能。方便起見,我打算將這個F#對象序列化成XML而不是二進制數據流。這意味著我需要使用XmlSerializer而不是BinaryFormatter。這本應沒有問題,但是在使用時候還是發生了一些小插曲。

定義類型

在F#中有多種定義方式。除了F#特有的Record類型外,在F#中也可以定義普通的“類”,如:

 

  1. #light  
  2. module XmlSerialization  
  3. type Post() =  
  4.     [<DefaultValue>]  
  5.     val mutable Title : string 
  6.     [<DefaultValue>]  
  7.     val mutable Content : string 
  8.     [<DefaultValue>] 

val mutable Tags : string array上面的代碼在XmlSerialization模塊中定義了一個Post類,其中包含三個公開字段。簡單地說,它和C#中的如下定義等價:

 

  1. public class Post  
  2. {  
  3.     public string Title;  
  4.     public string Content;  
  5.     public string[] Tags;  

可見,在定義這種簡單類型時,F#并沒有什么優勢,反而需要更多的代碼。

使用XmlSerializer進行序列化

原本我以為使用XmlSerializer來序列化一個對象非常容易,寫一個簡單的(泛型)函數就可以了:

  1. let byXmlSerializer (graph: 'a) =  
  2.     let serializer = new XmlSerializer(typeof<'a>)  
  3.     let writer = new StringWriter()  
  4.     serializer.Serialize(writer, graph)  
  5.     writer.ToString() 

使用起來更加不在話下:

 

  1. let post = new XmlSerialization.Post()  
  2. post.Title <- "Hello" 
  3. post.Content <- "World" 
  4. post.Tags <- [| "Hello""World" |]  
  5. let xml = XmlSerialization.byXmlSerializer(post) 

但是,在運行的時候,XmlSerializer的構造函數卻拋出了InvalidOperationException:

XmlSerialization cannot be serialized. Static types cannot be used as parameters or return types.
這句話的提示似乎是在說XmlSerialization是一個靜態類型——但這其實是F#的模塊啊。不過使用.NET Reflector查看編譯后的程序集便會發現,其實Post類是這樣定義的:

  1. public static class XmlSerialization  
  2. {  
  3.     public class Post { ... }  

雖然.NET中也有“模塊”的概念,但是它和F#中的模塊從各方面來講幾乎沒有相同之處。F#的模塊會被編譯為靜態類,自然模塊中的方法或各種函數便成為靜態類中的內嵌類型及方法。這本沒有問題,從理論上來說XmlSerializer也不該有問題,不是嗎?

可惜XmlSerializer的確有這樣的問題,我認為這是個Bug——但就算這是個Bug也無法解決目前的狀況。事實上,互聯網上也有人提出這個問題,可惜半年來都沒有人回應。

手動序列化

那么我又該怎么做呢?我想,算了,既然如此,我們進行手動序列化吧。反正就是簡單的對象,寫起來應該也不麻煩。例如在C#中我們便可以:

 

  1. public class Post  
  2. {  
  3.     ...  
  4.     public string ToXml()  
  5.     {  
  6.         var xml =   
  7.             new XElement("Post",  
  8.                 new XElement("Title"this.Title),  
  9.                 new XElement("Content"this.Content),  
  10.                 new XElement("Tags",  
  11.                     this.Tags.Select(t => new XElement("Tag", t))));  
  12.         return xml.ToString();  
  13.     }  

很簡單,不是嗎?但是用F#寫同樣的邏輯便有一些問題了,最終得到的結果是:

 

  1. type Post() =   
  2.     ...  
  3.  
  4.     member p.ToXml() =  
  5.         let xml = new XElement(XName.Get("Post"))  
  6.         xml.Add(new XElement(XName.Get("Title"), p.Title))  
  7.         xml.Add(new XElement(XName.Get("Content"), p.Content))  
  8.  
  9.         let tagElements = p.Tags |> Array.map (fun t -> new XElement(XName.Get("Tag"), t))  
  10.         xml.Add(new XElement(XName.Get("Tags"), tagElements))  
  11.           
  12.         xml.ToString() 

C#之所以可以寫的簡單,其中有諸多因素:

XElement的構造函數***使用了params object[],這意味著我們可以把參數“羅列”出來,而不需要顯式地構造一個數組。

XElement的構造函數接受的其實是XName類型參數,但字符串可以被隱式地轉化為XName類型。

XElement的構造函數可以將IEnumerable<XElement>對象轉化為獨立的元素。 但是,除了***一條外,其他兩個特性在F#里都無法享受到。因此,我們只能用命令式編程的方式編寫此類代碼。您可以發現,這樣的F#代碼幾乎可以被自動轉化為Java代碼。F#在寫這樣的代碼時實在沒有優勢。

使用DataContractSerializer

手動進行XML序列化雖然并不困難,但是實在麻煩。這不是一種通用的做法,我們必須為每個類型各寫一套序列化(和反序列化)邏輯,在類型字段有所改變的時候,序列化和反序列化的邏輯還必須有所變化。就在我打算寫一個簡單的,通用的XML序列化方法時,我忽然想到以前看到過的一篇文章,說是在.NET 3.0中發布了新的類庫:DataContractSerializer。

DataContractSerializer看似和WCF有關,如DataContractAttribute,DataMemberAttribute等標記最典型的作用也一直用在WCF里。但事實上,這些類型都是定義在System.Runtime.Serialization.dll中的,這意味著這些功能從設計之初與WCF分離開來,可以獨立使用。那么我們不如嘗試一下吧:

  1. let serialize (graph : 'a) =   
  2.     let serializer = new DataContractSerializer(typeof<'a>)  
  3.     let textWriter = new StringWriter();  
  4.     let xmlWriter = new XmlTextWriter(textWriter);  
  5.     serializer.WriteObject(xmlWriter, graph)  
  6.     textWriter.ToString() 

果然好用,DataContractSerializer并沒有出現XmlSerializer那樣傻乎乎地錯誤。自然,與之相對的反序列化函數也很容易寫:

  1. let deserialize<'a> xml =   
  2.     let serializer = new DataContractSerializer(typeof<'a>)  
  3.     let textReader = new StringReader(xml)  
  4.     let xmlReader = new XmlTextReader(textReader)  
  5.     serializer.ReadObject(xmlReader) :?> 'a 

試驗一下,看看效果?

 

  1. let post = new XmlSerialization.Post()  
  2. post.Title <- "Hello" 
  3. post.Content <- "World" 
  4. post.Tags <- [| "Hello""World" |]  
  5.  
  6. let xml = XmlSerialization.serialize post  
  7. let post' = XmlSerialization.deserialize<XmlSerialization.Post> xml 

經過更多試驗,我發現DataContractSerializer對于復雜類型的字段也可以正常應對,而得到這些功能也只需要在目標類型上標記一個SerializableAttribute就行了,更細節的控制也可以通過DataContractAttribute等進行控制。這樣看來,XmlSerializer似乎已經可以退出歷史舞臺了?

原文標題:F#中的XML序列化

鏈接: http://www.cnblogs.com/JeffreyZhao/archive/2010/01/03/fsharp-xml-serialization.html

責任編輯:彭凡 來源: 博客園
相關推薦

2009-11-16 09:05:46

CodeTimer

2009-02-24 10:09:02

XMLJava對象

2009-09-09 15:47:27

XML序列化和反序列化

2012-04-13 10:45:59

XML

2009-09-09 14:45:41

XML序列化和反序列化

2010-04-07 16:51:59

F#

2010-01-26 08:25:06

F#語法F#教程

2011-06-01 15:05:02

序列化反序列化

2009-08-19 09:42:34

F#并行排序算法

2021-11-18 11:48:46

ObjectInputJava

2018-03-19 10:20:23

Java序列化反序列化

2011-05-18 15:20:13

XML

2009-06-14 22:01:27

Java對象序列化反序列化

2009-09-09 17:14:24

XML序列化

2010-01-07 10:04:18

F#函數式編程

2011-06-01 14:26:11

序列化

2009-08-06 11:16:25

C#序列化和反序列化

2010-03-16 09:09:04

F#

2010-01-15 08:33:13

F#F#類型推斷F#教程

2010-01-08 13:25:07

ibmdwXML
點贊
收藏

51CTO技術棧公眾號

欧美三级一区| 国产91成人在在线播放| 黑人精品欧美一区二区蜜桃 | 国产精品免费网站在线观看| 亚洲国产高清一区| 神马久久影院| 精品视频一二| av老司机免费在线| 国产福利视频在线观看| 日韩精品视频无播放器在线看 | 久久精品嫩草影院| 里番在线播放| 中文字幕中文字幕在线中高清免费版 | 精品国产一区二区亚洲人成毛片| 亚洲图片欧美激情| 国产91富婆露脸刺激对白| 久久精品动漫| 亚洲黑丝一区二区| 国精品一区二区| 亚洲黄色影院| 国产精品美女| 亚洲精品免费观看| 欧美a级片一区| 一区二区三区在线观看免费| 精品国产网站| 91精品一区二区三区综合| 成人女性视频| 欧美国产一级| 综合久久精品| 国产亚洲在线| 国产高清久久久久| 成人av第一页| 亚洲视频资源在线| 亚洲第一狼人社区| 欧美日韩国产大片| 7777精品伊人久久久大香线蕉完整版 | 国产aaaaa毛片| baoyu777.永久免费视频| 中文字幕免费中文| 蝌蚪视频在线播放| gogo在线观看| 嫩草伊人久久精品少妇av杨幂| 国产精品日本一区二区不卡视频| 成人春色在线观看免费网站| 日韩三级av| 亚洲精品男同| 国产美女精品人人做人人爽| 福利一区在线观看| 国产欧美日韩不卡免费| 精品magnet| 亚洲欧美日韩精品| 777777777亚洲妇女| 国内精品久久国产| 妞干网这里只有精品| 国产wwwxx| 岛国中文字幕在线| 亚洲一区电影| 亚洲视频精品| 国产日韩欧美激情| 欧美日本一道本在线视频| 这里只有精品丝袜| 国产日韩欧美在线播放| 亚洲图片都市激情| 在线欧美一级视频| 亚洲不卡系列| 日韩一级大片| 久久亚洲影视婷婷| 日本韩国欧美一区| 欧美激情在线有限公司| 日本成人三级电影网站| 另类图片激情| 国产综合色激情| 免费在线观看成人av| 夜夜爽夜夜爽精品视频| 亚洲一二在线观看| 久99久在线| 最新亚洲伊人网| 男人的天堂久久| 国产99久久久国产精品免费看| 欧美午夜激情视频| 欧美中在线观看| xxxx18hd亚洲hd捆绑| 在线观看中文字幕的网站| 99精品美女| 亚洲精品老司机| 日韩在线视频导航| 最近中文字幕免费mv| 日本最新在线视频| 欧美 日韩 国产精品免费观看| 国产精品久久三| 欧美大片免费看| 久久天天躁狠狠躁夜夜爽蜜月| 一区二区三区四区五区视频| 黄色在线论坛| 亚洲女同在线| 777久久久精品| 国产日韩一区二区| 中国黄色在线视频| 亚洲经典一区| 色婷婷av一区二区三区gif| 国产欧美 在线欧美| 天堂在线看视频| 在线日韩网站| 亚洲高清在线精品| 亚洲一区美女视频在线观看免费| 污网站在线观看视频| 欧美黄污视频| 欧美三级在线播放| 欧美在线一区二区三区四区| 成人77777| 久久精品电影| 中文日韩在线观看| 国产又猛又黄的视频| 精品久久对白| 欧美日韩国产精品一区二区不卡中文| 国产精品网站大全| 日韩子在线观看| 精品一二三四区| 亚洲欧美制服中文字幕| 91成人在线观看喷潮教学| 66精品视频在线观看| 天天综合色天天综合| 欧美日韩精品一区| 99蜜月精品久久91| 亚洲福利电影网| 日韩av影视| 欧美日韩卡一| 一区二区久久久| 奇米影视首页 狠狠色丁香婷婷久久综合| 欧美日韩经典丝袜| 国产欧美日韩久久| 国产高清在线一区| 欧美视频免费看| 亚洲福利一区二区三区| 神马影院午夜我不卡影院| 高清国产一区二区三区四区五区| 午夜av一区二区三区| 成人精品在线视频| 日韩精品一区二区三区| 色偷偷成人一区二区三区91| 国产中文字幕二区| 亚洲大胆视频| 91av在线免费观看| 免费看电影在线| 国产欧美精品一区二区色综合朱莉| 动漫一区二区在线| 91精品国产乱码久久久竹菊| 欧美v亚洲v综合ⅴ国产v| 狠狠色一日本高清视频| 试看120秒一区二区三区| 91美女片黄在线观看91美女| 中文字幕在线中文| 久久国产精品无码网站| 老司机午夜网站| 成人免费观看视频| 少妇精品放荡导航| 精品国产免费人成电影在线观看四季 | 狠狠做深爱婷婷综合一区| 2025国产精品视频| 波多野结衣在线观看一区二区 | 欧美jizzhd欧美| 欧美日韩成人激情| 日韩欧美一起| 在线播放日韩av| 精品少妇3p| 99热99热| 国产精品99久久不卡二区| 韩国视频理论视频久久| 欧美视频免费一区二区三区| 欧美videos中文字幕| **国产精品| 国产精品成人av在线| 亚洲高清自拍| 国产成人无码a区在线观看视频| 国产日韩欧美不卡| 国内福利写真片视频在线| 欧美视频在线一区二区三区 | 欧美三级视频在线| 不卡在线视频| 亚洲性猛交xxxxwww| 久久大胆人体视频| 成人国产1314www色视频| 欧美日韩国内| 亚洲激情一区二区三区| 91视频观看免费| 99re6热在线精品视频播放| 欧美日韩成人在线一区| 九九久久国产| 高清av免费一区中文字幕| 成人免费视频app| 午夜在线视频| 国产综合香蕉五月婷在线| 91蝌蚪porny九色| 欧洲一区精品| 精品久久中出| 在线午夜精品| 亚洲美女自拍偷拍| 国产性色一区二区| 最近中文视频在线| 精品美女一区二区|