我正在尝试序列化继承对象列表。我可以根据其真实类型单独序列化每个对象,但是当它的基类型列表时,序列化程序会混淆,因为它期望序列化“基础”对象,但随后看到继承了“基础”的不同对象对象
有关如何轻松解决此问题的任何想法?我做了很多阅读,并没有找到一种优雅易于维护的方法来做到这一点。
尝试序列化:
'Define a list of the common inherited base for all print elements. ' This allows all types of print elements to be added to one list and in the user defined order ' Order is important for the layer of objects when 'drawing' them on the canvas during the on print options <XmlArrayAttribute("ElementsList")> 'Tell the XML Seralizer this is a list Public Elements As New List(Of CardItemBase) 'XML Serializer does not like this becuase the elements in this list are not CardItemBase, they are that + stuff, and it does not know what to do with stuff
以下是继承基类的两个项目示例,如果声明为真实类型,这两个项目将序列化(即使在列表中)。:
Public Class TextString 'Inherit the common properties for a card item Inherits CardItemBase 'Vars to hold string info to use when printing Public StringToPrint As String = String.Empty Public XLocation As Single = 0 Public YLocation As Single = 0 'Font info (store values instead of a Pen since Pen requires dispose and also does not work with Xml Serializing) Public Font As String = Nothing Public FontSize As Integer = 0 Public FontColor As System.Drawing.KnownColor = Drawing.KnownColor.Black 'Note, does NOT require dispose 'Constructor to force users to pass in all info Public Sub New() 'Create an empty Sub New Overload for use with XML Serializer End Sub Public Sub New(ByVal CardSide As CardSideOptions, ByVal InputStringToPrint As String, ByVal TextFont As String, ByVal TextSize As Integer, ByVal TextColor As System.Drawing.KnownColor, ByVal InputXLocation As Single, ByVal InputYLocation As Single) 'Set the inherited objects MyBase.New(CardSide:=CardSide) 'Save passed in info StringToPrint = InputStringToPrint Font = TextFont FontSize = TextSize FontColor = TextColor XLocation = InputXLocation YLocation = InputYLocation End Sub ''' <summary> ''' Return the ture type of this object as DriverJob.PrintElementTypes even if the item is nested in a CardItemBase list. ''' </summary> <XmlIgnore()> Public Overrides ReadOnly Property MyType() As PrintElementTypes Get Return PrintElementTypes.Text End Get End Property <XmlIgnore()> Public Overrides ReadOnly Property ToString() As String Get Try 'Create a string that descipes this object Dim ReturnStr As String = "" 'Concatinate a description of each element ReturnStr += "X: " & XLocation.ToString() & ", Y: " & YLocation.ToString() & ", " ReturnStr += Font & ", " & FontSize & ", " ReturnStr += FontColor.ToString() & ", " ReturnStr += "'" & StringToPrint & "'" 'Return the completed string. Return ReturnStr Catch ex As Exception 'Just return the error string Return ex.Message End Try End Get End Property End Class ''' <summary> ''' Sub class for passing images to print to the printing method. ''' </summary> Public Class Image 'Inherit the common properties for a card item Inherits CardItemBase 'Vars to hold image info to use when printing Public ImageFilePathToUse As String = "" Public XLocation As Single = 0 Public YLocation As Single = 0 Public Height As Single = 0 Public Width As Single = 0 'Constructor to force users to pass in all info Public Sub New() 'Create an empty Sub New Overload for use with XML Serializer End Sub Public Sub New(ByVal CardSide As CardSideOptions, ByVal InputImageFilePathToUse As String, Optional ByVal InputXLocation As Single = 0, Optional ByVal InputYLocation As Single = 0, Optional ByVal InputHeight As Single = 0, Optional ByVal InputWidth As Single = 0) 'Set the inherited objects MyBase.New(CardSide:=CardSide) 'Save passed in info ImageFilePathToUse = InputImageFilePathToUse XLocation = InputXLocation YLocation = InputYLocation Height = InputHeight Width = InputWidth End Sub ''' <summary> ''' Return the ture type of this object as DriverJob.PrintElementTypes even if the item is nested in a CardItemBase list. ''' </summary> <XmlIgnore()> Public Overrides ReadOnly Property MyType() As PrintElementTypes Get Return PrintElementTypes.Image End Get End Property ''' <summary> ''' Creates a simple string description of the object ''' </summary> <XmlIgnore()> Public Overrides ReadOnly Property ToString() As String Get Try 'Create a string that descipes this object Dim ReturnStr As String = "" 'Concatinate a description of each element ReturnStr += "X: " & XLocation.ToString() & ", Y: " & YLocation.ToString() & ", " ReturnStr += "Height: " & Height.ToString() & ", Width: " & Width.ToString() & ", " ReturnStr += ImageFilePathToUse 'Return the completed string. Return ReturnStr Catch ex As Exception 'Just return the error string Return ex.Message End Try End Get End Property End Class
答案 0 :(得分:1)
经过几个小时的阅读和测试后,我找到了一个适合我的解决方案。
在基类定义之上,可以使用XML include标记定义继承此基类的所有类型,以便不会混淆序列化程序。这在添加继承此基类的类时只添加了一个步骤,为了我的使用,我可以使用它。
以下是我添加的代码行:
'Class to hold common properties that may be needed for describing all card elements. This is intented to be inherited <XmlInclude(GetType(TextString)), XmlInclude(GetType(Line)), XmlInclude(GetType(Rectangle)), XmlInclude(GetType(Image)), XmlInclude(GetType(PrintAndTopcoatBlocking)), XmlInclude(GetType(MagstripeSetup)), XmlInclude(GetType(SmartCardSetup))> Public MustInherit Class CardItemBase