【问题标题】:How to XML Serialize a 'Type'如何 XML 序列化“类型”
【发布时间】:2010-09-22 09:30:30
【问题描述】:

如何序列化“类型”?

我想将具有属于对象类型的属性的对象序列化为 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] 放在哪里?这甚至可能吗?

【问题讨论】:

    标签: c# xml serialization


    【解决方案1】:

    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);}
        }
    }
    

    【讨论】:

    • 为了使 XML 更漂亮,您可以将 [XmlElement(ElementName = "T")] 属性添加到 tName 属性。
    • 两件事:私有字段不需要[XmlIgnore],并且T setter不需要更新名称。
    【解决方案2】:

    XML 序列化仅将对象的公共字段和属性值序列化为 XML 流。 XML 序列化不包含类型信息。例如,如果您有一个 Book 对象存在于 Library 命名空间中,则无法保证将其反序列化为相同类型的对象。 p>

    来源:Details of XML serialization | Microsoft Docs

    【讨论】:

    • 但在问题中 T 是公开的。
    • 此链接已损坏
    • 十多年后更新链接! :-)
    【解决方案3】:

    您可以实现IXmlSerializable 接口并使用Type.FullName(您可能还需要Type.AssemblyQualifiedName)进行序列化,并使用Assembly.GetType(string) 对您的类型元素进行反序列化。

    【讨论】:

      【解决方案4】:

      我最终将类型名称转换为字符串以将其保存为 XML。

      反序列化时,我加载所有 DLL 并将类型名称保存在字典中。当我使用类型名称加载 XML 时,我可以在字典键中查找名称并根据字典值知道类型。

      【讨论】:

        【解决方案5】:

        问题在于 XmlData.T 的类型实际上是“System.RuntimeType”(Type 的子类),遗憾的是它不是公开的。这意味着没有办法告诉序列化期望什么类型。我建议只序列化类型的名称,或 Jay Bazuzi 建议的完全限定名称。

        【讨论】:

          【解决方案6】:

          丑陋但有效。创建一个包含对象类型和序列化字符串的类。

          Class dummie
          {
              Type objType;
              string xml;
          }
          

          【讨论】:

            猜你喜欢
            • 2011-06-22
            • 1970-01-01
            • 2023-03-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多