4

I have an object array containing array of a different type that is not known at compile time, but turns out to be int[], double[] etc.

I want to save these arrays to disk and I don't really need to process their contents online, so I looking for a way to cast the object[] to a byte[] that I then can write to disk.

How can I achieve this?

3 Answers 3

3

You may use binary serialization and deserialization for Serializable types.

using System.Runtime.Serialization.Formatters.Binary;

BinaryFormatter binary = BinaryFormatter();
using (FileStream fs = File.Create(file))
{
    bs.Serialize(fs, objectArray);
}

Edit: If all these elements of an array are simple types then use BitConverter.

object[] arr = { 10.20, 1, 1.2f, 1.4, 10L, 12 };
using (MemoryStream ms = new MemoryStream())
{
    foreach (dynamic t in arr)
    {
        byte[] bytes = BitConverter.GetBytes(t);
        ms.Write(bytes, 0, bytes.Length);
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

My implementation is forced to convert to a byte array before data can be written, as the actual writing is done by a different class.
Use MemoryStream instead of FileStream. You could add sample data in your post.
I'm pretty sure this will do something else than just serializing the values. I have tried this, and for an object array containing two integers, I get a 39 byte stream!
Well you may use BitConverter.GetBytes(for all simple types) method.
2

You could do it the old fashioned way.

static void Main()
{
  object [] arrayToConvert = new object[] {1.0,10.0,3.0,4.0, 1.0, 12313.2342};

  if (arrayToConvert.Length > 0) {
     byte [] dataAsBytes;
     unsafe {
        if (arrayToConvert[0] is int) {
           dataAsBytes = new byte[sizeof(int) * arrayToConvert.Length];
           fixed (byte * dataP = &dataAsBytes[0]) 
              // CLR Arrays are always aligned
              for(int i = 0; i < arrayToConvert.Length; ++i) 
                 *((int*)dataP + i) = (int)arrayToConvert[i];
        } else if (arrayToConvert[0] is double) {
           dataAsBytes = new byte[sizeof(double) * arrayToConvert.Length];
           fixed (byte * dataP = &dataAsBytes[0]) {
              // CLR Arrays are always aligned
              for(int i = 0; i < arrayToConvert.Length; ++i) {
                 double current = (double)arrayToConvert[i];
                 *((long*)dataP + i) = *(long*)&current;        
              }
           }
        } else {
           throw new ArgumentException("Wrong array type.");
        }
     }

     Console.WriteLine(dataAsBytes);
  }
}

However, I would recommend that you revisit your design. You should probably be using generics, rather than object arrays.

1 Comment

I like this one, but I would create MemoryStream instead and use BinaryWriter to write to it... Nice, clean, tightly packed.
0

From here:

List<object> list = ...
byte[] obj = (byte[])list.ToArray(typeof(byte));

or if your list is complex type:

list.CopyTo(obj);

2 Comments

There is no overload of ToArray that takes arguments.
From the doc-link it seems that OfType filters, and doesn't convert. Indeed running your snippet produces an empty obj.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.