Serializing a Class within a Class (Previously Structures) 
Author Message
 Serializing a Class within a Class (Previously Structures)

Okay, I have 2 classes - empName and editInfo.  Each editInfo contains an
empName.  I could have 100 editInfo's all with the same empName(added in the
New constructor).  Previously I had structures to handle this information -
I changed them to classes because structures wouldn't hold this 'reference'
through serialization.

I do not want to do XML or SOAP serialization.  I have an application that
grabs 1-1,000,000 (exag.) classes held in 2 separate arraylists -
m_holdvalues(empName) and m_editedtimes(editInfo).  I have no problem
serializing/deserializing - unless I try to mix encode a file; ASCII/Binary.
I cannot seem to get all the information pulled out in the deserialization
routine and put back in the appropriate places.

If anyone knows how to do this and hold the 'reference' (which it really
isn't but is easiest to refer by) please fill me in.  I can show limited
code relating to this problem.  Thanks for any help in advance.

Best Regards,
Robert Oganezov



Mon, 12 Dec 2005 23:51:02 GMT  
 Serializing a Class within a Class (Previously Structures)
Robert,
What does the code you are using look like?

Can you post enough of your empName, editInfo classes & serialization code
so we can get a feel for what you are attempting?

Can you explain what you mean by 'mix encode a file; ASCII/Binary'?

I take it you are using the Binary Serialization?

Hope this helps
Jay



Quote:
> Okay, I have 2 classes - empName and editInfo.  Each editInfo contains an
> empName.  I could have 100 editInfo's all with the same empName(added in
the
> New constructor).  Previously I had structures to handle this
information -
> I changed them to classes because structures wouldn't hold this
'reference'
> through serialization.

> I do not want to do XML or SOAP serialization.  I have an application that
> grabs 1-1,000,000 (exag.) classes held in 2 separate arraylists -
> m_holdvalues(empName) and m_editedtimes(editInfo).  I have no problem
> serializing/deserializing - unless I try to mix encode a file;
ASCII/Binary.
> I cannot seem to get all the information pulled out in the deserialization
> routine and put back in the appropriate places.

> If anyone knows how to do this and hold the 'reference' (which it really
> isn't but is easiest to refer by) please fill me in.  I can show limited
> code relating to this problem.  Thanks for any help in advance.

> Best Regards,
> Robert Oganezov



Tue, 13 Dec 2005 00:03:44 GMT  
 Serializing a Class within a Class (Previously Structures)
Jay,
Thank you for the reply.  Below, I have the empName and editInfo class.
I have changed my serialization to use one file - temp.dat.

Previously I would write a file in ASCII.  After changes were made in my
app, I would append that ASCII file with the binary information.  I had
no problem getting the ASCII back out, however, when I tried to get the
binary deserialized a binary formatter version incompatibility error was
thrown.  I no longer append to the ASCII file - I just want to get the
serialization working.  Currently, I can only get one object to
deserialize.

Here is my code:

<Serializable()> _
Public Class editInfo
    Implements IComparable

    Private tag As Integer
    Private newEmpName As empName
    Private editDate As Date
    Private startTime As Long
    Private endTime As Long

    Public Overloads Function CompareTo(ByVal obj As Object) As Integer
Implements IComparable.CompareTo
        If TypeOf obj Is editInfo Then
            Dim objTag As editInfo = CType(obj, editInfo)

            Return
newEmpName.completeName.CompareTo(objTag.newEmpName.completeName)
'obj.newempname.completeName)
        End If
        Throw New ArgumentException("object is not an EmpName")
    End Function
    Public Sub New(ByVal tempTag As Integer, ByVal tempEmpName As
empName, ByVal tempDate As Date, ByVal tempStart As Long, ByVal tempEnd
As Long)
        tag = tempTag
        newEmpName = tempEmpName
        editDate = tempDate
        startTime = tempStart
        endTime = tempEnd
    End Sub
    Public Property IDTag() As Integer
        Get
            Return tag
        End Get
        Set(ByVal Value As Integer)
            tag = Value
        End Set
    End Property
    Public ReadOnly Property name() As String
        Get
            Return newEmpName.completeName
        End Get
    End Property
    Public ReadOnly Property showInfo()
        Get
            Dim info As String
            info = name.PadRight(50) & Space(10) & Format(workDate,
"MM/dd/yyyy") & Space(10) & Format(start, "00:00") & Space(10) &
Format(finish, "00:00")
            Return info
        End Get
    End Property
    Public Property workDate() As Date
        Get
            Return editDate
        End Get
        Set(ByVal Value As Date)
            editDate = Value
        End Set
    End Property
    Public Property start() As Long
        Get
            Return startTime '.ToString.Substring(0, 2) & ":" &
startTime.ToString.Substring(2, 2)
        End Get
        Set(ByVal Value As Long)
            startTime = Value
        End Set
    End Property
    Public Property finish() As Long
        Get
            Return endTime
        End Get
        Set(ByVal Value As Long)
            endTime = Value
        End Set
    End Property
End Class
<Serializable()> _
Public Class empName
    Implements IComparable

    Private tag As Integer
    Private empID As String
    Private firstName As String
    Private lastName As String
    <[NonSerialized]()> Private wholeName As String

    Public Overloads Function CompareTo(ByVal obj As Object) As Integer
Implements IComparable.CompareTo
        If TypeOf obj Is empName Then
            Return completeName.CompareTo(obj.completeName)
        End If
        Throw New ArgumentException("object is not an EmpName")
    End Function
    Public Sub New(ByVal tempTag As Integer, ByVal tempNum As String,
ByVal fName As String, ByVal lName As String)
        empID = tempNum
        firstName = fName
        lastName = lName
        tag = tempTag
    End Sub
    Public Property empTag() As Integer
        Get
            Return tag
        End Get
        Set(ByVal Value As Integer)
            tag = Value
        End Set
    End Property
    Public Property empNum() As String
        Get
            Return empID
        End Get
        Set(ByVal Value As String)
            empID = Value
        End Set
    End Property
    Public ReadOnly Property completeName() As String
        Get
            wholeName = Trim(lastName) & ", " & Trim(firstName)
            Return wholeName
        End Get
    End Property
    Public Property f_Name() As String
        Get
            Return firstName
        End Get
        Set(ByVal Value As String)
            firstName = Value
        End Set
    End Property
    Public Property l_Name() As String
        Get
            Return lastName
        End Get
        Set(ByVal Value As String)
            lastName = Value
        End Set
    End Property
End Class
 Private Sub mnuSave_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuSave.Click
        'Serialize into one big array list... Upon deserialization check
the type and add to the appropriate list
        Try
            'Dim myDir As String = m_fileName
            Dim myDir As String = "c:\temp\temp.dat" 'Change this

            Dim myFile As File
            ' If myFile.Exists(myDir) Then 'Check to ensure that file
exists
            '   Dim stream As IO.FileStream

            Dim bf As New
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
            'stream = New IO.FileStream(myDir, IO.FileMode.CreateNew,
IO.FileAccess.ReadWrite)
            Dim stream As New IO.FileStream(myDir, IO.FileMode.Open,
IO.FileAccess.ReadWrite)
            'stream.Seek(0, SeekOrigin.End)'Don't need to seek

            bf.Serialize(stream, m_editedTimes) 'Serialize entire array
list

            bf.Serialize(stream, m_holdValues) 'serialized entire array
list
            stream.Flush()
            stream.Close()
            bf = Nothing
            stream = Nothing
            ' End If
            'Disable save menu option to prevent saving over data...
Data can now only be saved here
            m_menuName.Enabled = False
'After this are 8 catch statements
end try
end sub

Public Function runDeserialization(ByVal myPos As Long) As Object ':
implements IFormatter
        Dim retObj As Object
        Dim stream As IO.FileStream

        Dim bf As New
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
        'IFormatter(bf = New Binaryformatter())

        Dim endChar As String = "+"
        ' Dim bArray As Byte() = New Byte(100) {}
        ' Dim tempbuffer As String
        ' Dim buffer As String

        stream = New IO.FileStream(m_fileName, IO.FileMode.Open,
IO.FileAccess.ReadWrite)
        ' Dim input As StreamReader = New StreamReader(stream,
System.Text.Encoding.ASCII)

        'Do
        '   tempbuffer = input.ReadLine

        ' buffer = Convert.tempbuffer
        'Loop Until tempbuffer = "+"

        'stream.Read(bArray, 0, 100)
        'stream.Position = myPos + 1
        'stream.Seek(myPos, SeekOrigin.Begin)

        retObj = bf.Deserialize(stream)

        stream.Close()
        stream = Nothing
        bf = Nothing

        Return retObj
    End Function
    Public Sub loadData(ByVal myPos As Long)
        'Try
        'BigList will hold all objects being deserialized
        Dim bigList As ArrayList = CType(runDeserialization(myPos),
ArrayList)
        Dim obj As Object

        bigList.TrimToSize()

        'Cycle through all deserialized object and insert into
appropriate class
        For Each obj In bigList
            'If object is editinfo, add to editInfo arraylist
            If TypeOf obj Is editInfo Then
                Dim aClass As editInfo
                aClass = CType(obj, editInfo)

                m_editedTimes.Add(aClass)

                'm_editedTimes.Add(CType(obj, editInfo))
                'If object is not edit info then it shoule be empname
            ElseIf TypeOf obj Is empName Then
                Dim aClass As empName
                aclass = CType(obj, empName)
                m_holdValues.Add(aclass)

                'm_holdValues.Add(CType(obj, empName))
                'Commented out to read debugging info
                'Throw an error if something goes wrong - not the
correct information being loaded
                'Else
                '   Dim bad As Exception
                '  Throw bad
            End If
        Next
        ' Catch bad As Exception
        '    MsgBox("Sorry, an incorrect type has been loaded.  Please
contact 1-800-472-1007 for assistance.", MsgBoxStyle.Exclamation,
"Incorrect Format in Load")
        '   End Try
    End Sub

Okay Jay, that should about do it for what the serialization contains.
After I get the information deserialized and put back into array lists I
try to bind comoboxes to those lists.

As I said before, I am only getting one object to deserialize, thus my
application is erroring out when I try to rebind to the data.

Any help will be GREATLY appreciated; I've been stuck on this one for a
while and I'm running out of time.  Thanks a lot for any help you can
offer!

-Toby

Robert Oganezov

P.O. Box 711
Gurnee, IL 60031

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!



Tue, 13 Dec 2005 06:09:58 GMT  
 Serializing a Class within a Class (Previously Structures)
Robert,
Your runDeserialization routine should deserialize both m_editedTimes &
m_holdValues as you explicitly serialize both into the stream. For each
Serialize you call on a stream, you need to call Deserialize on the stream.
Which means your LoadData routine can go away.

Minimum runDeserializeation is:

    Dim bf As New BinaryFormater
    Dim stream as New FileStream(m_fileName, FileMode.Open)

    m_editTimes = DirectCast(bf.Deserialize(stream), ArrayList)
    m_holdValues = DirectCast(bf.Deserialize(stream), ArrayList)

    stream.Close()

However! the problem is going to be that any editInof objects that refer to
empName objects when you serialized will have different objects when you
deserialize. (each serialize/deserialize pair does not know about the other
pair).

What I would recommend you do is both m_editedTimes & m_holdValues into a
new class, mark this new class as Serializeable

    <Serializable()> _
    Public Class Data

            Private m_EditedTimes As New ArrayList
            Private m_holdValues As New ArrayList

            Public Readonly Property EditedTimes as ArrayList
                Get
                    Return m_EditedTimes
                End Get
            End Property

            Public Readonly Property holdValues as ArrayList
                Get
                    Return m_holdValues
                End Get
            End Property

    End Class

    Private m_data As Data

Then you only Serialize & Deserialize the m_data variable.

Hope this helps
Jay


Quote:
> Jay,
> Thank you for the reply.  Below, I have the empName and editInfo class.
> I have changed my serialization to use one file - temp.dat.

> Previously I would write a file in ASCII.  After changes were made in my
> app, I would append that ASCII file with the binary information.  I had
> no problem getting the ASCII back out, however, when I tried to get the
> binary deserialized a binary formatter version incompatibility error was
> thrown.  I no longer append to the ASCII file - I just want to get the
> serialization working.  Currently, I can only get one object to
> deserialize.

> Here is my code:

> <Serializable()> _
> Public Class editInfo
>     Implements IComparable

>     Private tag As Integer
>     Private newEmpName As empName
>     Private editDate As Date
>     Private startTime As Long
>     Private endTime As Long

>     Public Overloads Function CompareTo(ByVal obj As Object) As Integer
> Implements IComparable.CompareTo
>         If TypeOf obj Is editInfo Then
>             Dim objTag As editInfo = CType(obj, editInfo)

>             Return
> newEmpName.completeName.CompareTo(objTag.newEmpName.completeName)
> 'obj.newempname.completeName)
>         End If
>         Throw New ArgumentException("object is not an EmpName")
>     End Function
>     Public Sub New(ByVal tempTag As Integer, ByVal tempEmpName As
> empName, ByVal tempDate As Date, ByVal tempStart As Long, ByVal tempEnd
> As Long)
>         tag = tempTag
>         newEmpName = tempEmpName
>         editDate = tempDate
>         startTime = tempStart
>         endTime = tempEnd
>     End Sub
>     Public Property IDTag() As Integer
>         Get
>             Return tag
>         End Get
>         Set(ByVal Value As Integer)
>             tag = Value
>         End Set
>     End Property
>     Public ReadOnly Property name() As String
>         Get
>             Return newEmpName.completeName
>         End Get
>     End Property
>     Public ReadOnly Property showInfo()
>         Get
>             Dim info As String
>             info = name.PadRight(50) & Space(10) & Format(workDate,
> "MM/dd/yyyy") & Space(10) & Format(start, "00:00") & Space(10) &
> Format(finish, "00:00")
>             Return info
>         End Get
>     End Property
>     Public Property workDate() As Date
>         Get
>             Return editDate
>         End Get
>         Set(ByVal Value As Date)
>             editDate = Value
>         End Set
>     End Property
>     Public Property start() As Long
>         Get
>             Return startTime '.ToString.Substring(0, 2) & ":" &
> startTime.ToString.Substring(2, 2)
>         End Get
>         Set(ByVal Value As Long)
>             startTime = Value
>         End Set
>     End Property
>     Public Property finish() As Long
>         Get
>             Return endTime
>         End Get
>         Set(ByVal Value As Long)
>             endTime = Value
>         End Set
>     End Property
> End Class
> <Serializable()> _
> Public Class empName
>     Implements IComparable

>     Private tag As Integer
>     Private empID As String
>     Private firstName As String
>     Private lastName As String
>     <[NonSerialized]()> Private wholeName As String

>     Public Overloads Function CompareTo(ByVal obj As Object) As Integer
> Implements IComparable.CompareTo
>         If TypeOf obj Is empName Then
>             Return completeName.CompareTo(obj.completeName)
>         End If
>         Throw New ArgumentException("object is not an EmpName")
>     End Function
>     Public Sub New(ByVal tempTag As Integer, ByVal tempNum As String,
> ByVal fName As String, ByVal lName As String)
>         empID = tempNum
>         firstName = fName
>         lastName = lName
>         tag = tempTag
>     End Sub
>     Public Property empTag() As Integer
>         Get
>             Return tag
>         End Get
>         Set(ByVal Value As Integer)
>             tag = Value
>         End Set
>     End Property
>     Public Property empNum() As String
>         Get
>             Return empID
>         End Get
>         Set(ByVal Value As String)
>             empID = Value
>         End Set
>     End Property
>     Public ReadOnly Property completeName() As String
>         Get
>             wholeName = Trim(lastName) & ", " & Trim(firstName)
>             Return wholeName
>         End Get
>     End Property
>     Public Property f_Name() As String
>         Get
>             Return firstName
>         End Get
>         Set(ByVal Value As String)
>             firstName = Value
>         End Set
>     End Property
>     Public Property l_Name() As String
>         Get
>             Return lastName
>         End Get
>         Set(ByVal Value As String)
>             lastName = Value
>         End Set
>     End Property
> End Class
>  Private Sub mnuSave_Click(ByVal sender As System.Object, ByVal e As
> System.EventArgs) Handles mnuSave.Click
>         'Serialize into one big array list... Upon deserialization check
> the type and add to the appropriate list
>         Try
>             'Dim myDir As String = m_fileName
>             Dim myDir As String = "c:\temp\temp.dat" 'Change this

>             Dim myFile As File
>             ' If myFile.Exists(myDir) Then 'Check to ensure that file
> exists
>             '   Dim stream As IO.FileStream

>             Dim bf As New
> System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
>             'stream = New IO.FileStream(myDir, IO.FileMode.CreateNew,
> IO.FileAccess.ReadWrite)
>             Dim stream As New IO.FileStream(myDir, IO.FileMode.Open,
> IO.FileAccess.ReadWrite)
>             'stream.Seek(0, SeekOrigin.End)'Don't need to seek

>             bf.Serialize(stream, m_editedTimes) 'Serialize entire array
> list

>             bf.Serialize(stream, m_holdValues) 'serialized entire array
> list
>             stream.Flush()
>             stream.Close()
>             bf = Nothing
>             stream = Nothing
>             ' End If
>             'Disable save menu option to prevent saving over data...
> Data can now only be saved here
>             m_menuName.Enabled = False
> 'After this are 8 catch statements
> end try
> end sub

> Public Function runDeserialization(ByVal myPos As Long) As Object ':
> implements IFormatter
>         Dim retObj As Object
>         Dim stream As IO.FileStream

>         Dim bf As New
> System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
>         'IFormatter(bf = New Binaryformatter())

>         Dim endChar As String = "+"
>         ' Dim bArray As Byte() = New Byte(100) {}
>         ' Dim tempbuffer As String
>         ' Dim buffer As String

>         stream = New IO.FileStream(m_fileName, IO.FileMode.Open,
> IO.FileAccess.ReadWrite)
>         ' Dim input As StreamReader = New StreamReader(stream,
> System.Text.Encoding.ASCII)

>         'Do
>         '   tempbuffer = input.ReadLine

>         ' buffer = Convert.tempbuffer
>         'Loop Until tempbuffer = "+"

>         'stream.Read(bArray, 0, 100)
>         'stream.Position = myPos + 1
>         'stream.Seek(myPos, SeekOrigin.Begin)

>         retObj = bf.Deserialize(stream)

>         stream.Close()
>         stream = Nothing
>         bf = Nothing

>         Return retObj
>     End Function
>     Public Sub loadData(ByVal myPos As Long)
>         'Try
>         'BigList will hold all objects being deserialized
>         Dim bigList As ArrayList = CType(runDeserialization(myPos),
> ArrayList)
>         Dim obj As Object

>         bigList.TrimToSize()

>         'Cycle through all deserialized object and insert into
> appropriate class
>         For Each obj In bigList
>             'If object is editinfo, add to editInfo arraylist
>             If TypeOf obj Is editInfo Then
>                 Dim aClass As editInfo
>                 aClass = CType(obj, editInfo)

>                 m_editedTimes.Add(aClass)

>                 'm_editedTimes.Add(CType(obj, editInfo))
>                 'If object is not edit info then it shoule be empname
>             ElseIf TypeOf obj Is empName Then
>                 Dim aClass As empName
>                 aclass = CType(obj, empName)
>                 m_holdValues.Add(aclass)

>                 'm_holdValues.Add(CType(obj, empName))
>                 'Commented out to read debugging info

...

read more »



Tue, 13 Dec 2005 09:11:33 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Class modules 97 - Refering to array within a custom class module

2. Classes within Classes

3. How-To Access Class Members Within The Same Class

4. Raising events from a class within a collection class

5. Arrays of Classes within Classes

6. memory leaks and classes within classes

7. Not getting Events from classes within classes.

8. Dim obj As New Class crt Dim Obj As Class = New Class

9. derive class from protected class in base class

10. SERIALIZING A CLASS THAT CONTAINS A COLLECTION

11. Serialize Directoryinfo class using XMLSerializer

12. Serializing DirectoryInfo Class for WebService

 

 
Powered by phpBB® Forum Software