2009-09-08 80 views
0

XML Serialization from MSDNXML序列化VS反映在C#

序列化和反序列化對象 和從XML文檔。使用XmlSerializer可以控制 對象如何編碼爲XML。

Reflection from MSDN

反射提供了封裝組件, 模塊和類型的對象(的 型型)。您可以使用 反射動態地創建類型的實例 ,類型綁定到 現有對象,或從現有對象獲取類型 並調用它的 方法或訪問其字段和屬性 。如果您在代碼中使用 屬性,則可使用Reflection 訪問它們。

據我瞭解,我可以使用XML序列化在運行時創建對象?換句話說,假設我有一個數據庫,我可以在幾個表中定義我的「類」或「對象」。然後,我可以獲取對象數據的XML,然後在運行時創建對象。

我也可以將那些編譯爲庫的對象隨時可用,然後使用Reflection來訪問它的函數。

從您的理解來看,這兩個概念中的哪一個可以在犧牲最少性能的同時賦予最大的靈活性?如果您可以提供詳細的解釋和考慮事項以及可能的代碼示例,則可獲得獎勵積分。

回答

2

序列化和反射不是相互排斥的。你可以肯定地序列化和反序列化一個對象,然後使用反射來修改它。

系列化

序列化是簡單的拍攝對象狀態的「快照」,這樣就可以潛在地恢復該快照在以後的時間概念。

如果您希望將對象存儲在持久性存儲中,如果您不需要在特定值之後查詢,則序列化是一個不錯的選擇。

注意,存在至少兩種不同類型的串行化的:

  • XML序列,表示對象爲XML。由於它是XML,這種表示(至少在理論上)是人類可讀的並且可以互操作。
  • 二進制序列化,它只是將一個對象存儲和讀取爲一個字節數組。這種表示是專有的,不可讀。

反射

反射是使用對象的元數據來操縱的對象的能力。例如,您可以決定將字符串「Foo」分配給給定對象的所有可寫字符串屬性,而不考慮對象的類型。

當設計時不知道物體的類型時,這是最有趣的。

0

要使用反序列化對象,您需要知道要反序列化到的類型。所以你不能只用xml創建你的對象,而不需要在程序集中定義它的類型。

你可以做的是在代表序列化對象的數據庫中存儲xml。然後,您可以從數據庫加載xml,並根據需要將其反序列化爲對象實例。 xml的源代碼不需要是序列化的對象,所以如果需要的話可以手動創建它。

使用反射會是一種不同的情況。通過反射,您可以獲取對象並獲取對象上可用的方法和屬性的列表。然後,您可以編寫與對象動態協作的代碼,而不管它們實現哪種類型。這種方法的問題在於,代碼編寫和讀取笨拙,並且很容易引入僅在運行時可見的錯誤。最重要的是,由於使用反射引入的開銷,代碼將運行緩慢。

而不是使用反射我會讓我的對象實現一些衆所周知的接口,我可以將它們投射到。這將允許我的代碼是類型安全的,我可以避免反射的麻煩。代碼運行得更快,可讀性更高。

0

無法使用XML序列化或反射來即時創建新類型。這些技術只適用於現有的類型。如果您需要在運行時創建新類型,則必須使用其他方法。然而,由於您只能使用反射來訪問這些類型,因此生成蒼蠅的類型的用處有限。在.NET的下一個主要版本中使用動態運行時將爲您提供更多創建和使用動態類型的選項。

XML序列化用於序列化來自衆所周知的格式(XML)的對象。反射更加通用,使您能夠在運行時檢查類型信息,並在編譯時無需知道類型就可以處理對象。您也可以使用反射來進行序列化,但與XML序列化相比,它更麻煩。

+0

這不是真的,你不能用Reflection創建新的類型。看看Reflection Emit。 – 2009-09-08 10:59:28

+0

@Mark Seemann。 'System.Reflection.Emit'命名空間是我在寫「另一種方法」時想到的。我不認爲這是「正常」反射的一部分,而是編譯器和代碼生成器生成代碼而不是反思代碼的框架。你的「反思」的定義當然可能不同。 – 2009-09-08 12:04:09