Reflection and order of the fields

  • Thread starter Thread starter Frank D Lombardo
  • Start date Start date
F

Frank D Lombardo

I am attempting to use Reflection to send an object over a serial port. I
won't know the exact type of the object until run-time. If I call
GetFields(), is there any guarantee on the order the fields are returned?
Would it help if I used a struct instead of a class? I need to send the
fields in a known and consistent order. I would also like this code to work
on the Compact Framework.


Thanks,
 
Frank,

I am curious, if you are sending an object over the wire, then why not
just use serialization (assuming that .NET is on the other side of the
wire).

The order of the fields is not guaranteed. Some reasonable assumptions
would be to get them in declarative order, and alphabetical, but I am not
sure. If you need a specific order, I would recommend getting the specific
fields and then ordering them yourself.

Hope this helps.
 
Frank D Lombardo said:
I am attempting to use Reflection to send an object over a serial port. I
won't know the exact type of the object until run-time. If I call
GetFields(), is there any guarantee on the order the fields are returned?

I wouldn't expect so, no.
Would it help if I used a struct instead of a class? I need to send the
fields in a known and consistent order. I would also like this code to work
on the Compact Framework.

Why not just get the fields, then sort them alphabetically? That way
they *will* be consistent.
 
I guess I didn't tell you all of the requirements. The device at the other
end is an instrument I am trying to control. My code needs to run on both
the full framework and the compact framework. The objects I want to send
are command objects that have different data fields depending on the nature
of the command.

Because of my specific serialization requirements, I was hoping to write my
own generic command serializer that would use reflection to determine the
run-time data fields of the command and send them over the wire. I'm just
not sure if I can rely on the declarative order of the fields being the
order that they are returned from GetFields().

--
Frank D. Lombardo
Turning Point Technology, Inc.
Frank_AT_TurningPointOnline_DOT_com



Nicholas Paldino said:
Frank,

I am curious, if you are sending an object over the wire, then why not
just use serialization (assuming that .NET is on the other side of the
wire).

The order of the fields is not guaranteed. Some reasonable assumptions
would be to get them in declarative order, and alphabetical, but I am not
sure. If you need a specific order, I would recommend getting the specific
fields and then ordering them yourself.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Frank D Lombardo said:
I am attempting to use Reflection to send an object over a serial port. I
won't know the exact type of the object until run-time. If I call
GetFields(), is there any guarantee on the order the fields are returned?
Would it help if I used a struct instead of a class? I need to send the
fields in a known and consistent order. I would also like this code to work
on the Compact Framework.


Thanks,
 
Frank said:
Because of my specific serialization requirements, I was hoping to write my
own generic command serializer that would use reflection to determine the
run-time data fields of the command and send them over the wire. I'm just
not sure if I can rely on the declarative order of the fields being the
order that they are returned from GetFields().

But this technique breaks all the normal rules of object oriented
programming :-)

Why don't you want the command objects to be able to
serialize/deserialize themselves? There shouldn't be any reason to use
reflection here, and even if GetFields() could return the field in some
predetermined order, are you going to otherwise ensure that both ends of
this link are always be using the same versions of these command
objects? If not, you need a more tolerant serialization mechanism.
 
I do want the commands to serialize/deserialize themselves. The goal here
is to have the Command base class contain the logic to serialize/deserialize
the specific instance of a command. The actual commands will subclass the
Command class. That way, when a specific command's data structure changes,
the serialize/deserialize code doesn't have to be updated. Do you see a
flaw in this design?
 
Frank,
Although I suspect the fields are returned in a known order, today, I would
not trust they would be returned in the same order tomorrow.

Seeing as order of fields is important I would recommend custom
serialization/deserialization routines based on the BinaryReader &
BinaryWriter classes in the System.IO namespace.

The following article gives a C# example of how do this.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp09182003.asp

Hope this helps
Jay
 
Hi frank,

AFAIK the CF does not support serialization, therefore you will have to
implement it by your own. An idea that comes to my head is declaring an
interface ( or a base class with a virtual method ) with a method that makes
a byte array with all what is needed to recreate the object in the other
end, then you can easily send it through the serial port, now as the exact
type of the object is not know you will need a kind of command ID to
determine the type of the object , and the size of the data stream
following, the stream can looks like:

----------------------------------------------------------------------------
----------------------------------------------------------------------------
-----
| CommandID | object's data size | object data
..................................| CommandID| CommandID | object's data
size | object data .................................| ....
----------------------------------------------------------------------------
----------------------------------------------------------------------------
-----

You then can do something like this in the other end:

Command nextCommand = CommandFactory.CreateCommand(
ComHandler.ReadCommandId( ) );
byte[] commanddata = ComHandler.ReadByteArray( ComHandler.ReadDataSize() );
nextCommand.Deserialize( commanddata );


where ComHandler is a class or instance that read from the COM , it has
method like ReadCommandId() to read the next byte(s) needed to identify a
command .
You should also use an object factory to centralize and decouple the
creation of commands.
and it;s the responsability of the command itself to be able to recreate it
self from a byte[].


Hope this help,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

Frank D Lombardo said:
I guess I didn't tell you all of the requirements. The device at the other
end is an instrument I am trying to control. My code needs to run on both
the full framework and the compact framework. The objects I want to send
are command objects that have different data fields depending on the nature
of the command.

Because of my specific serialization requirements, I was hoping to write my
own generic command serializer that would use reflection to determine the
run-time data fields of the command and send them over the wire. I'm just
not sure if I can rely on the declarative order of the fields being the
order that they are returned from GetFields().

--
Frank D. Lombardo
Turning Point Technology, Inc.
Frank_AT_TurningPointOnline_DOT_com



message news:%[email protected]...
Frank,

I am curious, if you are sending an object over the wire, then why not
just use serialization (assuming that .NET is on the other side of the
wire).

The order of the fields is not guaranteed. Some reasonable assumptions
would be to get them in declarative order, and alphabetical, but I am not
sure. If you need a specific order, I would recommend getting the specific
fields and then ordering them yourself.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Frank D Lombardo said:
I am attempting to use Reflection to send an object over a serial
port.
I to
work
 
Back
Top