alxp

Hi,

Is there any direct way of getting the size of a variable of type object[]

Thanks



Re: Visual C# General size of object[]

Peter Ritchie

You can get the length of the array, but outside of unsafe code nothing besides intrinsic value types really has a size.




Re: Visual C# General size of object[]

alxp

Thanks, so I stick with the ugly way of iterating trough the array while comparing types :/

public ushort SizeOf(object[] args)

{

try

{

ushort TotalBytes = 0;

foreach (object obj in args)

{

if (obj is ushort) { TotalBytes += 2; }

else if (obj is byte) { TotalBytes++; }

else if (obj is ushort[]) { TotalBytes += (ushort)(((ushort[])obj).Length * 2); }

else if (obj is byte[]) { TotalBytes += (ushort)(((byte[])obj).Length); }

else return 0;

}

return TotalBytes;

}

catch (Exception ex)

{

return 0;

}

}





Re: Visual C# General size of object[]

Tim Stall

Hey, alxp.

I don't have a perfect answer here - but maybe serialize the object to a xml, or using a binary serializer, and then measure the length of that serialized string. The technique has its problems, but (1) it's quick to implement, (2) it handles arrays and different object types (no switch required), and (3) it's useful for relative comparisons.

Here's a code snippet to serialize to XML (You can probably convert it to a binary one easily): http://timstall.dotnetdevelopersjournal.com/rapid_development_with_the_xmlserializer.htm

.

Tim





Re: Visual C# General size of object[]

Zamial

Remember serializing to XML only serializes the Public properties.

If you want more control you get into the realms of custom serialization.

I personally prefer binary as well but that's just preference, if you must pass XML around then the XML serializer is the way to go Wink, obviously.

As Peter said though you can't really do this from managed code





Re: Visual C# General size of object[]

Peter Ritchie

Reference objects don't have a size (unless marshaled) so the CLR is free to do whatever it needs to do with them.

Maybe if you explain why you need the size we can offer an alternative.






Re: Visual C# General size of object[]

alxp

I have a function that builds different network messages base on passed arguments (params object[]). In the header section of each message I need to specify the size of the body in bytes (object[]). I wrote a function to return the number of bytes from object[] and it works fine, I just dont like having to iterate through each object, check its type and then assign the number of bytes to the return variable. I wonder if there is a more elegant way to do this.

Object[] might contain ushort[] and byte[] types

Thank you





Re: Visual C# General size of object[]

Peter Ritchie

So, you don't want the size of each object you want the size of the data that the object serializes. If you're serializing the object to memory to find the size, that's the correct size; but you're likely serializing each object twice. What networking classes are you using to communicate We can probably infer how it's serializing and show an alternative way of sending the information you want without serializing twice.






Re: Visual C# General size of object[]

alxp

I have to use Socket.

It goes something like this:

public byte[] newMessage(char MsgType, params object[] args)

{

byte[] msgBuffer = null;

ushort msgSz = this.SizeOf(args);

msgBuffer = new byte[msgSz + 12]; //Message body + 12 bytes of header section

Sets the header section for the message

.....

Fill the buffer with the message body (args) starting at position 12,

with byte swapping for big-endian compatibility.

...

return msgBuffer;

}

The call to the function could be:

byte[] b = newMessage ( ' X ', byte1, byte2, ushort1, ushort2, new byte[] {byte1,byte2}, new ushort[] {ushort1, ushort2});

Or just

byte[] b = newMessage ( ' X ', byte1);

Regards,





Re: Visual C# General size of object[]

Peter Ritchie

If you're communicating between two managed applications, I would do something like:

Code Snippet

using (MemoryStream stream = new MemoryStream())

{

System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

foreach (object o in args)

{

bf.Serialize(stream, o);

}

Int32 length = stream.Length;

// send length, or header, etc...

socket.Send(BitConverter.GetBytes(length));

// send stream...

socket.Send(stream.GetBuffer());

}

On the receiving end you and read each object (after the header) with the socket's stream. For example:

Code Snippet

int start = (int)stream.Position;

while (stream.Position < start + length)

{

object o = bf.Deserialize(stream);

// do something with o

}