日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用泛型来实现编译时期的类型推断

發布時間:2025/3/20 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用泛型来实现编译时期的类型推断 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
第一章都是講泛型的,距離上一篇Effective C#的隨筆已經是很久以前的事情了。。。? 今天Item4,講的是泛型的類型推斷功能。東西好不好,都是比較出來了,當然也不是絕對的好或者絕對的不好。? 首先上一段不用泛型的代碼。 1: public static class XmlPersistenceManager 2: { 3: public static object LoadFromFile(Type typeToLoad, string filePath) 4: { 5: XmlSerializer factory = new XmlSerializer(typeToLoad); 6: if (File.Exists(filePath)) { 7: using (TextReader tr = new StreamReader(filePath)) { 8: object rVal = factory.Deserialize(tr); 9: return rVal; 10: } 11: } 12: return default(object);//null 13: } 14: public static void SaveToFile(string filePath, object obj) 15: { 16: Type theType = obj.GetType(); 17: XmlSerializer factory = new XmlSerializer(theType); 18: using (var sw = new StreamWriter(filePath, false)) { 19: factory.Serialize(sw, obj); 20: } 21: } 22: }

兩個方法,一個讀取Xml生成Object的實例,另一個把一個obj保存成一個Xml。這里有幾個缺點

①每次調用LoadFromFile方法,必須有一個類型轉換,從Object轉成自己要的類型,寫的時候肯定不會報錯的,因為Object是所有類型的基類,但是運行的時候,就不一定了~~ 。

②這是一個性能問題。每次調用這兩個方法的時候,都重新new 了一個XmlSerializer對象。Framework的設計者是會盡量降低new對象的代價,但畢竟是需要創建,然后銷毀一些零時的變量。

看到第二點,大家都會想到把XmlSerializer類型對象factory作為一個XmlPersistenceManager的靜態成員變量。

看到第二點可能會寫出下面的代碼。

1: public static class XmlPersistenceManager2 2: { 3: private static XmlSerializer factory; 4: public static object LoadFromFile(Type typeToLoad, string filePath) 5: { 6: if (factory == null) 7: factory = new XmlSerializer(typeToLoad); 8:? 9: if (File.Exists(filePath)) { 10: using (TextReader tr = new StreamReader(filePath)) { 11: object rVal = factory.Deserialize(tr); 12: return rVal; 13: } 14: } 15: return default(object);//null 16: } 17: public static void SaveToFile(string filePath, object obj) 18: { 19: Type theType = obj.GetType(); 20: if (factory == null) factory = new XmlSerializer(theType); 21: using (var sw = new StreamWriter(filePath, false)) { 22: factory.Serialize(sw, obj); 23: } 24: } 25: }

性能問題是解決了,但是,明顯,有個bug。20行,先ClassA類型的obj調用,factory生成一個實例,木有問題;然后來一個ClassB類型的obj調用,factory != null ;然后,22行,調用,異常就來了。 原先我以為是不會出錯的,充其量應該只是生成一個空的xml文件,但原文用了Exception這個詞,然后自己測試了一下。證明,我錯了,確實是Exception,再看一下代碼,factory實例化的時候傳入了參數theType。為什么要傳這個參數呢?我想應該還是性能問題吧。new 一個 XmlSerializer 之后肯定不會只(反)序列化同類型的對象一次。

要解決這個bug也很容易,用一個Dictionary來存XmlSerializer對象。。。但是這樣意味著要寫更多代碼,寫更多編譯器和JIT引擎可以幫你實現的代碼。

接下來泛型上場,原文叫“correct answer”。

1: public static class GenericXmlPersistenceManager<T> 2: { 3: private static XmlSerializer factory; 4: public static T LoadFromFile(string filePath) 5: { 6: if (File.Exists(filePath)) { 7: using (XmlReader inputStream = XmlReader.Create(filePath)) { 8: if (factory == null) factory = new XmlSerializer(typeof(T)); 9: T rVal = (T)factory.Deserialize(inputStream); 10: return rVal; 11: } 12: } 13: return default(T); 14: } 15: public static void SaveToFile(string filePath, T data) 16: { 17: using (XmlWriter writer = XmlWriter.Create(filePath)) { 18: if (factory == null) factory = new XmlSerializer(typeof(T)); 19: factory.Serialize(writer, data); 20: } 21: } 22: }

代碼上和最初的版本沒有什么太大差異。解決了原先的幾個問題。

①類型轉換。泛型類中的LoadFromFile方法,返回的類型其實已經被限定了,就是T類型,至于T具體是什么類型,就看自己在調用的時候尖括號之間寫的具體的值了。

②性能問題和那個Exception bug。用了靜態變量,緩存了XmlSerializer對象,當序列化同個類型的obj的時候,不需再去重新new一個XmlSerializer。并且,如果傳入了不同類型的obj,也會重新new一個對應類型的XmlSerializer 類型的factory,這樣就不會報錯。(想到一個問題,寫完之后查資料了解一下)。

?

最后一段:

很多時候如果用了Type類型的參數,通常都可以定義出一個泛型的版本。編譯器就會 “Create the Specific version for you.”。

轉載于:https://www.cnblogs.com/sheldon-lou/p/3443734.html

總結

以上是生活随笔為你收集整理的用泛型来实现编译时期的类型推断的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。