Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / March 2006

Tip: Looking for answers? Try searching our database.

Serialization Gurus?  Unexpected Binary Behavior

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
google@fluxpc.com - 02 Mar 2006 21:13 GMT
I'm seeing something very odd with binary serialization, and I wanted
to make sure I'm not misunderstanding what goes on under the hood.

Let's say you have a graph with two objects, one referencing the other
(parent/child):
   A -> B
Now you have a totally separate but identical graph with an A' and B':
  A' -> B'
Property-by-property these objects have the same primitive values.
They're clones, essentially.  And let's say there's a grandparent X.
  X -> A' -> B'

What I *think* I'm seeing is that the bytes coming out of binary
serialization with an input of A are different than those coming from
binary serialization with an input of A'.  The only thing I can seem to
point at as a cause is the sheer existence of X, even though A' has no
direct knowledge of X.

If this is the case, it definitely breaks everything I thought I knew
about binary serialization.  I'm actually hoping that I'm totally wrong
here, but after spending about 8 hrs digging deeply into the issue,
this is the only straw left to grasp at.

My specific issue is of course much more complicated.  My A->B graph
has more items, with some circular references between them.  There are
some structs.  Maybe even some Equals overrides (which I know get used
by XML serialization).  I've taken a fine toothed comb to this using
the "Make Object ID" functionality of the Watch window...  And for the
life of me I can't locate any difference between "the graph starting
from A" and "the graph starting from A' "...  But yet the binary
serializations of each, when compared byte-by-byte, are different.  One
is always exactly 183 bytes longer.  Any ideas would be greatly
appreciated.

This is .NET 2.0, C#.  

Thanks,

James
tommaso.gastaldi@uniroma1.it - 02 Mar 2006 22:02 GMT
Hi James,

in my opinion, while it is often useful to have *at runtime* cross
reference, you do not need usually to serialize both. Usually you have
a cross reference between 2 object where  one act like a kind of
"parent" (or "container") and the lther like a child:

class Parent
 Public Child as Child
...
end class

class Child
  <nonserialized()>  Public Parent
...

function RestoreChild(Parent as Parent)
    me.Parent = Parent
end function

end class

when you "restore" (possible Deserializations+Relinks) the child you
would also relink, at runtime, the Parent, which usually is restored
(possible Deserializations+Relinks) before the child. Sometimes for the
restore it is necessary to backup some info will will allow to relink
the objects.

I would also suggest to define an interface, say
"IObjectWithBackupRestore" to automatize the backup/restored of the
objects (can be both key or Values) stored within hashtables,
SortedList, etc. Think for instance to the case, common in real world
application, where the Comparer used for a SortedList depends on
members which need to be relinked or restored, before being able to use
the restored (deserialized) SortedList (or else you would get null
pointers)...

Actually for complex application one has to implement a whole engine
and strategies to deal effectively with this issue (restoring the
runtime environment), that in my opinion is one that requires time and
insight for a programmer to get right in all its nuances. It is even
possible that people who never build really complex applications are
not really aware of the whole problem ,,,

-tom

This is an extreme simplification, but the principle is applicable in
several occasion.

google@fluxpc.com ha scritto:

> I'm seeing something very odd with binary serialization, and I wanted
> to make sure I'm not misunderstanding what goes on under the hood.
[quoted text clipped - 35 lines]
>
> James
google@fluxpc.com - 04 Mar 2006 21:10 GMT
Tom,

Thanks for the response.  We actually aren't serializing for the
purpose of storage (or data transmission), at least not yet.  But when
we do, your recommendations will come in handy.  We are currently
serializing only as a way to compare two object graphs in a "by value"
sense.  Unfortunately, it looks like binary serialization isn't cut out
for this purpose.

James
tommaso.gastaldi@uniroma1.it - 05 Mar 2006 00:43 GMT
Hi James,

I am not clear what you are actually doing, but it sounds that, if it's
not a job for Icomparable, Icomparer ... ,  then it is probably
something for "System.Reflection". Perhaps something on the lines of:
(altought I can't see for the moment how this could be useful)

Assume a form with 1 button. This compares 2 instances of an object.
Returns: FALSE, TRUE. Just the general idea, must be refined...

'---------------------------

Imports System.Reflection

Class MyObj
   Public R As New System.Text.StringBuilder
   Public V As String = "Tom"
End Class

Public Class Form1
   Inherits System.Windows.Forms.Form

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

       Dim MyObj1 As New MyObj
       Dim MyObj2 As New MyObj
       MsgBox(CompareObjs(MyObj1, MyObj2))

       MyObj1.R = MyObj2.R
       MsgBox(CompareObjs(MyObj1, MyObj2))

   End Sub

   Function CompareObjs(ByVal Obj1 As Object, ByVal Obj2 As Object) As
Boolean

       'Fields
       Dim FieldInfos As FieldInfo() =
Obj1.GetType.GetFields((BindingFlags.Static Or _

BindingFlags.Instance Or _

BindingFlags.NonPublic Or _

BindingFlags.Public))
       For Each FieldInfo As FieldInfo In FieldInfos
           With FieldInfo
               If IsReference(FieldInfo.GetValue(Obj2)) Then
                   Dim V1 As Object = FieldInfo.GetValue(Obj1)
                   Dim V2 As Object = FieldInfo.GetValue(Obj2)
                   If Not Object.ReferenceEquals(V1, V2) Then Return
False
               Else
                   If Not Object.Equals(FieldInfo.GetValue(Obj1),
FieldInfo.GetValue(Obj2)) Then Return False
               End If
           End With
       Next FieldInfo

       'Properties
       Dim PropertyInfos As PropertyInfo() =
Obj1.GetType.GetProperties
       For Each PropertyInfo As PropertyInfo In PropertyInfos
           With PropertyInfo
               '...
           End With
       Next PropertyInfo

       '...

       Return True

   End Function

End Class

'---------------------------

in case don't be afraid to email me... sounds like you are doing
something interesting ... ;-)

Enjoy

-tom

google@fluxpc.com ha scritto:

> Tom,
>
[quoted text clipped - 6 lines]
>
> James

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.