如何对“Type”进行XML序列化

12

如何序列化“Type”?

我想将一个具有对象类型属性的对象序列化为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]呢?这可行吗?
6个回答

20

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
1
两件事情:[XmlIgnore] 不需要在私有字段上使用,而且 T 的 setter 不需要更新名称。 - reve_etrange

3
你可以使用 IXmlSerializable 接口来实现,使用 Type.FullName(你可能还需要 Type.AssemblyQualifiedName)进行序列化和 Assembly.GetType(string) 进行反序列化。

3

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

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


3
XML序列化将对象的公共字段和属性值序列化为XML流。XML序列化不包括类型信息。例如,如果您有一个存在于Library命名空间中的Book对象,则不能保证它将被反序列化为相同类型的对象。
来源:XML序列化详细信息|Microsoft Docs

但在问题中,T是公共的。 - Frep D-Oronge
这个链接已经损坏了。 - Slagmoth
超过十年后更新了链接! :-) - M. Jahedbozorgan

1

丑陋但有效。创建一个类,其中包括对象类型和序列化字符串。

例如

Class dummie
{
    Type objType;
    string xml;
}

1
问题在于XmlData.T的类型实际上是"System.RuntimeType"(Type的子类),但不幸的是它不是公共的。这意味着没有办法告诉序列化程序要期望哪些类型。我建议只序列化类型的名称,或者像Jay Bazuzi建议的那样序列化完全限定名称。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接