Charles,
The only way out of the "series of If" is to create a collection of objects
that convert individual types to Bytes. I would put these objects in a
HashTable that I use Type as the key to the HashTable.
As you need to have the specific value to convert it from a value to an
array of Bytes. However! I would probably use the if over this method...
Something like (unchecked):
Public MustInherit Class Converter
Public MustOverride Function GetBytes(obj As Object) As Byte()
End Class
' Consider making this a Singleton
Public Class IntegerConverter
Inherits Converter
Public Overriders Function GetBytes(obj As Object) As Bytes()
Return BitConverter.GetBytes(DirectCast(obj, Integer))
End Function
End Class
' Consider making this a Singleton
Public Class ByteConverter
Inherits Converter
Public Overriders Function GetBytes(obj As Object) As Bytes()
Return BitConverter.GetBytes(DirectCast(obj, Byte))
End Function
End Class
Dim converters As New HashTable
converters.Add(GetType(Byte), New ByteConverter)
converters.Add(GetType(Integer), New IntegerConverter)
Dim stream As New MemoryStream
Dim writer As New BinaryWriter(stream)
Dim fields() As FieldInfo = MyStruct.GetType().GetFields()
For Each fld As FieldInfo In fields
Dim converter As Converter = converters.Item(fld.FieldType)
writer.Write(converter.GetBytes(fld.GetValue(MyStruct)))
Next
For nested structures you can simply use Recursion, based on if there is a
predefined Converter or not (converters.Item returned Nothing).
You do realize that you CANNOT rely on the order of the fields returned by
Type.GetFields! The order will change in .NET 2.0!!! My understanding is it
was changed as its more efficient to return the fields in no particular
order, then ensuring they are in a specific order!
I don't have the reference handy, I understand that there is a class
similiar to BitConverter that will ensure that types are little-endian as
opposed to big endian.
Alternatively one or more of the members of the
System.RunTime.InteropService.Marshal class may be useful. For example
Marshal.StructureToPtr followed by series (loop) of Marshal.ReadByte calls.
Personally (Ultimately) for this problem I use a BinaryWriter & BinaryReader
and read & write individual fields to ensure that the fields are written in
the correct order & the correct sizes. I would not attempt to generalize
this to a single routine, that relies on undocumented behavior (the order of
GetFields).
The following article offers using a BinaryReader & BinaryWriter to
serializing a class to a NetworkStream, you can use a FileStream and have
the same effect.
http://msdn.microsoft.com/library/default.asp?url=/library/en-s/dncscol/html/csharp09182003.asp
The example is in C#, however it should be easily converted to VB.NET, post
if you need help.
Hope this helps
Jay