跨项目序列化派生类遇XmlSerializer报错,如何解决类型未预期问题?
解决跨项目派生类的XML序列化问题
问题原因
当使用基类Car的泛型序列化器序列化派生类SpecialCar实例时,XmlSerializer在编译期仅知晓基类类型,无法识别运行时传入的派生类,因此抛出类型未预期的错误。由于基类项目无法引用派生类项目,直接在Car类上添加XmlInclude特性不可行。
解决方案
修改基类项目中的泛型序列化器,增加支持传入额外类型的重载方法,在创建XmlSerializer时显式告知需要处理的派生类型。
1. 修改基类项目的Seriallizer类
添加重载的序列化方法,接受额外类型数组参数:
Public Class Seriallizer(Of T) ' 原无参方法,调用重载方法 Function SerializeObjToString(obj As T) As String Return SerializeObjToString(obj, Nothing) End Function ' 新增重载方法,支持传入额外类型 Function SerializeObjToString(obj As T, additionalTypes As Type()) As String Dim serializer As XmlSerializer Dim memStream As New MemoryStream Dim xmlWriter As New XmlTextWriter(memStream, Encoding.UTF8) Try ' 根据是否有额外类型选择XmlSerializer构造函数 If additionalTypes IsNot Nothing AndAlso additionalTypes.Length > 0 Then serializer = New XmlSerializer(GetType(T), additionalTypes) Else serializer = New XmlSerializer(GetType(T)) End If serializer.Serialize(xmlWriter, obj) Dim xml As String xml = Encoding.UTF8.GetString(memStream.GetBuffer()) xml = xml.Substring(xml.IndexOf(Convert.ToChar(60))) xml = xml.Substring(0, xml.LastIndexOf(Convert.ToChar(62)) + 1) Return xml Catch e As Exception MsgBox($"Error writing data to string: {e.Message}") Finally xmlWriter.Close() memStream.Close() xmlWriter = Nothing serializer = Nothing memStream = Nothing End Try Return "" End Function End Class
2. 在派生类项目中调用序列化方法
调用时传入SpecialCar的类型,告知XmlSerializer需要处理该派生类型:
Dim spezicalCar As New SpecialCar spezicalCar.Name = "Demo Car" spezicalCar.VentorName = "Demo Vendor" Dim serializer As New Seriallizer(Of Car) ' 传入包含SpecialCar的类型数组 Dim str As String = serializer.SerializeObjToString(spezicalCar, {GetType(SpecialCar)})
原理说明
XmlSerializer提供了带Type[]参数的构造函数,用于指定编译期未知但运行时需要序列化的派生类型。这种方式无需修改基类的特性,避免了基类项目对派生类项目的依赖,完美解决跨项目派生类的序列化问题。
内容的提问来源于stack exchange,提问作者gegy
相关产品推荐
相关产品推荐

