Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Xml反序列化为System.Type_C#_Xml_Xml Deserialization - Fatal编程技术网

C# Xml反序列化为System.Type

C# Xml反序列化为System.Type,c#,xml,xml-deserialization,C#,Xml,Xml Deserialization,我正在尝试反序列化一段XML,该XML将.NET类型指定为System.type的实例。给定 <SomeObject> <SomeType>System.String, mscorlib</SomeType> </SomeObject> 令人恼火的是,我以前确实做过这件事,但没有访问源代码,也记不起来,事实证明,如果给定所需的关键字(“Xml”、“反序列化”、“类型”几乎提供了所有信息),那么研究解决方案是非常困难的 根据我的记忆,我在Som

我正在尝试反序列化一段XML,该XML将.NET类型指定为
System.type
的实例。给定

<SomeObject>
  <SomeType>System.String, mscorlib</SomeType>
</SomeObject>
令人恼火的是,我以前确实做过这件事,但没有访问源代码,也记不起来,事实证明,如果给定所需的关键字(“Xml”、“反序列化”、“类型”几乎提供了所有信息),那么研究解决方案是非常困难的


根据我的记忆,我在
SomeType
属性上添加了一个简单的
属性
,然后
XmlSerializer
从那里开始处理它。有人知道我需要什么属性或者我记错了什么属性吗?

如果您不想拥有类型为
string
(此问题的常见解决方案)的附加属性,您可以像这样使用代理类:

public class XmlTypeProxy : IXmlSerializable {
    private string _typeName;

    public XmlTypeProxy() {

    }

    public XmlTypeProxy(string typeName) {
        _typeName = typeName;
    }

    public XmlSchema GetSchema() {
        return null;
    }

    public void ReadXml(XmlReader reader) {
        _typeName = reader.ReadString();
    }

    public void WriteXml(XmlWriter writer) {
        writer.WriteString(_typeName);
    }

    public static implicit operator Type(XmlTypeProxy self) {
        return Type.GetType(self._typeName);
    }

    public static implicit operator XmlTypeProxy(Type self) {
        return new XmlTypeProxy(self.AssemblyQualifiedName);
    }
}
这个类所做的只是将类型程序集限定名存储为字符串,并定义从
类型到
类型的隐式转换运算符。然后您只需要使用
xmlement
属性修饰
SomeType
,并指定它的
Type
XmlTypeProxy

public class SomeObject {
    [XmlElement(Type = typeof(XmlTypeProxy))]
    public Type SomeType { get; set; }
}
现在,由于存在从
Type
XmlTypeProxy
(反之亦然)的隐式转换,序列化和反序列化都将按预期工作。

而我已将的答案标记为正确(如果您反序列化多个
Type
属性),实际上,我最终采用了一种更简单的方法

根据答案,我修改了
SomeObject
to

public class SomeObject
{
    public string SomeTypeName
    {
        get { return SomeType.AssemblyQualifiedName; }
        set
        {
            var converter = new TypeNameConverter();
            SomeType = (Type)converter.ConvertFrom(value);
        }
    }

    [XmlIgnore]
    public Type SomeType { get; set; }
}

虽然单个属性的代码较短,但它不如公认的答案那么健壮。我在这里记录有两种方法可以帮助其他人。

在这种情况下,只需使用字符串。@jdweng,如果我找不到更好的方法,仍然是一个选项,但我非常确定有一个.NET
属性可以用来自动处理它。它类似于这个问题吗@简单,非常接近。你知道这是否被包装成一个专用的
属性
?在没有代理类的情况下应该可以做到这一点(不过,如果我找不到任何东西,我会将其标记为已接受)。例如,在设置自定义配置节时(当我以前这样做时),您可以直接将配置元素反序列化为
类型
,而无需中介
XmlTypeProxy
。在.NET内部的某个地方,有一种方法可以一步完成这项工作……自定义配置部分与纯XmlSerializer不同,其中涉及的代码要多得多。你没有错,但我觉得还有一种方法。“自定义配置节”方法可以通过
[TypeConverter(typeof(TypeNameConverter))]
实现这一点,但是
XmlSerializer
没有使用这一点-链中缺少一部分…@DiskJunky XmlSerializer的设计非常糟糕(至少按照现代标准),有很多事情它不能做,或者很难做。
public class SomeObject
{
    public string SomeTypeName
    {
        get { return SomeType.AssemblyQualifiedName; }
        set
        {
            var converter = new TypeNameConverter();
            SomeType = (Type)converter.ConvertFrom(value);
        }
    }

    [XmlIgnore]
    public Type SomeType { get; set; }
}