gpt4 book ai didi

c# - 我可以在不实现 IXmlSerializable 的情况下为 XmlSerializer 提供自定义序列化吗?

转载 作者:可可西里 更新时间:2023-11-01 03:10:10 25 4
gpt4 key购买 nike

我们正在使用 XmlSerializer,我想为某些类提供自定义序列化。但是,我并不总是能够修改相关类的源代码,否则我只能让它实现 IXmlSerializable。有什么办法吗?

最佳答案

这是代理反序列化助手的一个简单示例:

给定一个我们无法在类级别直接控制序列化的类型:

public sealed class Class //contrived example
{
public string Property {get;set;}
}

我们需要反序列化的 xml:

<Class>
<Property>Value</Property>
</Class>

您可以创建一个代理类型来手动处理目标类型的反序列化过程,如下所示:

[XmlRoot("Class")] // <-- Very important
public sealed class ClassSerializerProxy : IXmlSerializable
{
public Class ClassValue {get;set;}

public System.Xml.Schema.XmlSchema GetSchema(){return null;}
public void WriteXml(System.Xml.XmlWriter writer){}

public void ReadXml(System.Xml.XmlReader reader)
{
var x = XElement.ReadFrom(reader) as XElement;
this.ClassValue = new Class();
//again this is a simple contrived example
this.ClassValue.Property = x.XPathSelectElement("Property").Value;
}
}

用法是:

void Main()
{
// get the xml value somehow
var xdoc= XDocument.Parse(@"<Class><Property>Value</Property></Class>");

// deserialize the xml into the proxy type
var proxy = Deserialize<ClassSerializerProxy>(xdoc);

// read the resulting value
var value = proxy.ClassValue;
}

public object Deserialize(XDocument xmlDocument, Type DeserializeToType)
{
XmlSerializer xmlSerializer = new XmlSerializer(DeserializeToType);
using (XmlReader reader = xmlDocument.CreateReader())
return xmlSerializer.Deserialize(reader);
}

现在加入一些泛型和扩展方法,我们可以为最终(异常处理除外)版本稍微清理一下调用站点:

用法:

void Main()
{
var xml = @"<Class><Property>Value</Property></Class>";

var value = xml.DeserializeWithProxy<ClassSerializerProxy,Class>();

value.Dump();
}

您的实例类型:

public sealed class Class
{
public string Property {get;set;}
}

代理类型必须实现的接口(interface)

public interface ISerializerProxy<TInstanceType> where TInstanceType : class
{
TInstanceType Value { get; }
}

示例代理现在实现了新接口(interface)

[XmlRoot("Class")]
public sealed class ClassSerializerProxy : IXmlSerializable, ISerializerProxy<Class>
{
public Class Value {get;set;}

public System.Xml.Schema.XmlSchema GetSchema(){return null;}
public void WriteXml(System.Xml.XmlWriter writer){}

public void ReadXml(System.Xml.XmlReader reader)
{
var x = XElement.ReadFrom(reader) as XElement;
this.Value = new Class();
this.Value.Property = x.XPathSelectElement("Property").Value;
}
}

反序列化方法现在是 string 的扩展方法,可以与任何代理类型一起使用。

public static class ExtensionMethods
{
public static TInstanceType DeserializeWithProxy<TProxyType,TInstanceType>(this string xml)
where TProxyType : ISerializerProxy<TInstanceType>
where TInstanceType : class
{
using (XmlReader reader = XDocument.Parse(xml).CreateReader())
{
var xmlSerializer = new XmlSerializer(typeof(TProxyType));
return (xmlSerializer.Deserialize(reader) as ISerializerProxy<TInstanceType>).Value;
}
}
}

关于c# - 我可以在不实现 IXmlSerializable 的情况下为 XmlSerializer 提供自定义序列化吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17236823/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com