2008-11-14 77 views
12

如何序列化一個「類型」?如何將XML序列化「類型」

我想將序列化爲XML的對象具有屬性是一種對象的類型。這個想法是,當它被反序列化時,我可以創建一個該類型的對象。

public class NewObject 
{ 
} 

[XmlRoot] 
public class XmlData 
{ 
    private Type t; 

    public Type T 
    { 
     get { return t; } 
     set { t = value; } 
    } 
} 
    static void Main(string[] args) 
    { 
     XmlData data = new XmlData(); 
     data.T = typeof(NewObject); 
     try 
     { 
      XmlSerializer serializer = new XmlSerializer(typeof(XmlData)); 
      try 
      { 
       using (FileStream fs = new FileStream("test.xml", FileMode.Create)) 
       { 
        serializer.Serialize(fs, data); 
       } 
      } 
      catch (Exception ex) 
      { 

      } 
     } 
     catch (Exception ex) 
     { 

     } 
    } 

我得到這個異常: 「是沒有預料到的類型ConsoleApplication1.NewObject使用XmlInclude或SoapInclude屬性來指定不是靜態已知類型的。」

我在哪裏把[XmlInclude]?這甚至有可能嗎?

回答

3

XML序列化僅將對象的公共字段和屬性值序列化爲XML流。 XML序列化不包含類型信息。例如,如果你有一個存在於圖書館命名空間的Book對象,也不能保證,這將是反序列化爲同一類型的對象。

來源:MSDN: Introducing XML Serialization

+0

但在問題T是公共的。 – 2011-11-04 11:39:26

3

你可能實現IXmlSerializable界面,並使用Type.FullName(您可能還需要Type.AssemblyQualifiedName)序列化和Assembly.GetType(string)你的類型元素的反序列化。

3

我最終的型號名稱轉換爲字符串,將其保存爲XML。

反序列化時,我加載所有DLL並將類型和類型的名稱保存在字典中。當我使用類型名稱加載XML時,我可以在字典鍵中查找該名稱,並根據字典值知道該類型。

1

問題是XmlData.T的類型實際上是「System.RuntimeType」(類型的一個子類),遺憾的是它不是公共的。這意味着沒有辦法告訴serialise什麼類型的期望。我建議只按照Jay Bazuzi的建議序列化該類型的名稱或完全限定的名稱。

1

醜陋,但它的工作原理。創建一個包含對象類型和序列化字符串的類。

Class dummie 
{ 
    Type objType; 
    string xml; 
} 
17

Type類不能被序列化,因爲System.RuntimeType不是我們的代碼訪問,這是一個內部CLR類型。您可以通過使用類型的名稱來解決此問題,如下所示:

public class c 
{  
    [XmlIgnore] 
    private Type t; 
    [XmlIgnore] 
    public Type T { 
     get { return t; } 
     set { 
       t = value; 
       tName = value.AssemblyQualifiedName; 
      } 
    } 

    public string tName{ 
     get { return t.AssemblyQualifiedName; } 
     set { t = Type.GetType(value);} 
    } 
} 
+1

爲了使XML更加美觀,可以在`tName`屬性中添加一個`[XmlElement(ElementName =「T」)]`屬性。 – derkyjadex 2012-04-20 10:12:07