【问题标题】:VB.NET XML Serialize a List of Inherited ObjectsVB.NET XML 序列化继承对象列表
【发布时间】:2017-05-25 20:47:06
【问题描述】:

我正在尝试序列化继承对象的列表。我可以在根据其真实类型声明每个对象时单独序列化每个对象,但是当它是基本类型的列表时,序列化程序会感到困惑,因为它希望序列化一个“基本”对象,但随后会看到继承了“基本”的不同对象对象。

关于如何轻松解决此问题的任何想法?我已经阅读了大量内容,但没有找到一种优雅且易于维护的方式来做到这一点。

尝试序列化:

        '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

【问题讨论】:

    标签: vb.net xmlserializer


    【解决方案1】:

    经过几个小时的阅读和测试,我找到了适合我的解决方案。

    在基类定义之上,可以使用 XML 包含标记定义继承此基类的所有类型,这样序列化器就不会混淆。当添加继承这个基类的类时,这只会增加一个步骤,为了我的使用,我可以忍受这个。

    这是我添加的代码行:

        '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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-22
      • 1970-01-01
      • 1970-01-01
      • 2010-12-15
      • 1970-01-01
      相关资源
      最近更新 更多