2017-05-25 1 views
0

J'essaie de sérialiser une liste d'objets hérités. Je peux sérialiser chaque objet individuellement quand il est déclaré selon son vrai type, mais quand c'est une liste du type de base, le sérialiseur est confus parce qu'il s'attend à sérialiser un objet "base" mais ensuite voir différents objets qui ont hérité de la "base" objet.XML VB.NET sérialiser une liste d'objets hérités

Des idées pour résoudre facilement ce problème? J'ai fait beaucoup de lecture et je n'ai pas trouvé une façon élégante et facile de maintenir cela.

de sérialisation:

 '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 

Voici deux exemples d'éléments qui ont hérité la base, toutes deux sérialisera (même dans une liste) si elle est déclarée comme vrai type .:

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 

Répondre

0

Après quelques heures de lecture et d'essais, j'ai trouvé une solution tha Je vais travailler pour moi. Au-dessus de la définition de la classe de base, la balise d'inclusion XML peut être utilisée pour définir tous les types qui ont hérité de cette classe de base afin que le sérialiseur ne soit pas confondu. Cela ajoute une seule étape à faire lors de l'ajout de classes qui héritent de cette classe de base, pour mon utilisation, je peux vivre avec cela.

Voici ligne de code I ajouté:

'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