简体   繁体   English

如何 XML 序列化“类型”

[英]How to XML Serialize a 'Type'

How do I serialize a 'Type'?如何序列化“类型”?

I want to serialize to XML an object that has a property that is a type of an object.我想将具有对象类型的属性的对象序列化为 XML。 The idea is that when it is deserialized I can create an object of that type.这个想法是,当它被反序列化时,我可以创建一个该类型的对象。

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)
        {

        }
    }

I get this exception: "The type ConsoleApplication1.NewObject was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."我收到此异常:“不需要类型 ConsoleApplication1.NewObject。使用 XmlInclude 或 SoapInclude 属性指定静态未知的类型。”

Where do I put the [XmlInclude]?我把 [XmlInclude] 放在哪里? Is this even possible?这甚至可能吗?

Type class cannot be serialized because System.RuntimeType is not accessible to our code, it is an internal CLR type. Type类不能被序列化,因为System.RuntimeType不能被我们的代码访问,它是一个内部 CLR 类型。 You may work around this by using the type's name instead, like this:您可以通过使用类型名称来解决此问题,如下所示:

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

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

I ended up converting the Type name to a string to save it to XML.我最终将类型名称转换为字符串以将其保存为 XML。

When deserializing, I load all the DLLs and save the name of the type and type in a dictionary.反序列化时,我加载所有 DLL 并将类型和类型的名称保存在字典中。 When I load the XML with the Type Name, I can look up the name in the dictionary key and know the type based on the dictionary value.当我加载带有类型名称的 XML 时,我可以在字典键中查找名称并根据字典值知道类型。

XML serialization serializes only the public fields and property values of an object into an XML stream. XML 序列化仅将对象的公共字段和属性值序列化为 XML 流。 XML serialization does not include type information. XML 序列化不包括类型信息。 For example, if you have a Book object that exists in the Library namespace, there is no guarantee that it will be deserialized into an object of the same type.例如,如果您有一个 Book 对象存在于 Library 命名空间中,则不能保证它会被反序列化为相同类型的对象。

Source: Details of XML serialization |来源: XML 序列化详解 | Microsoft Docs 微软文档

The problem is that the type of XmlData.T is actually "System.RuntimeType" (a subclass of Type), which unfortunately is not public.问题在于 XmlData.T 的类型实际上是“System.RuntimeType”(Type 的子类),不幸的是它不是公开的。 This means there is no way of telling the serialise what types to expect.这意味着无法告诉序列化期望什么类型。 I suggest only serializing the name of the type, or fully qualified name as Jay Bazuzi suggests.我建议只序列化类型的名称,或者像 Jay Bazuzi 建议的那样完全限定名称。

Ugly but it works.丑陋,但它的工作原理。 Make a Class which includes the object type and the serialized string.创建一个包含对象类型和序列化字符串的类。

ex前任

Class dummie
{
    Type objType;
    string xml;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM