[c#] Convert any object to a byte[]

I am writing a prototype TCP connection and I am having some trouble homogenizing the data to be sent.

At the moment, I am sending nothing but strings, but in the future we want to be able to send any object.

The code is quite simple at the moment, because I thought everything could be cast into a byte array:

void SendData(object headerObject, object bodyObject)
{
  byte[] header = (byte[])headerObject;  //strings at runtime, 
  byte[] body = (byte[])bodyObject;      //invalid cast exception

  // Unable to cast object of type 'System.String' to type 'System.Byte[]'.
  ...
}

This of course is easily enough solved with a

if( state.headerObject is System.String ){...}

The problem is, if I do it that way, I need to check for EVERY type of object that can't be cast to a byte[] at runtime.

Since I do not know every object that can't be cast into a byte[] at runtime, this really isn't an option.

How does one convert any object at all into a byte array in C# .NET 4.0?

This question is related to c# .net object byte

The answer is


Combined Solutions in Extensions class:

public static class Extensions {

    public static byte[] ToByteArray(this object obj) {
        var size = Marshal.SizeOf(data);
        var bytes = new byte[size];
        var ptr = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(data, ptr, false);
        Marshal.Copy(ptr, bytes, 0, size);
        Marshal.FreeHGlobal(ptr);
        return bytes;
   }

    public static string Serialize(this object obj) {
        return JsonConvert.SerializeObject(obj);
   }

}

checkout this article :http://www.morgantechspace.com/2013/08/convert-object-to-byte-array-and-vice.html

Use the below code

// Convert an object to a byte array
private byte[] ObjectToByteArray(Object obj)
{
    if(obj == null)
        return null;

    BinaryFormatter bf = new BinaryFormatter();
    MemoryStream ms = new MemoryStream();
    bf.Serialize(ms, obj);

    return ms.ToArray();
}

// Convert a byte array to an Object
private Object ByteArrayToObject(byte[] arrBytes)
{
    MemoryStream memStream = new MemoryStream();
    BinaryFormatter binForm = new BinaryFormatter();
    memStream.Write(arrBytes, 0, arrBytes.Length);
    memStream.Seek(0, SeekOrigin.Begin);
    Object obj = (Object) binForm.Deserialize(memStream);

    return obj;
}

One additional implementation, which uses Newtonsoft.Json binary JSON and does not require marking everything with the [Serializable] attribute. Only one drawback is that an object has to be wrapped in anonymous class, so byte array obtained with binary serialization can be different from this one.

public static byte[] ConvertToBytes(object obj)
{
    using (var ms = new MemoryStream())
    {
        using (var writer = new BsonWriter(ms))
        {
            var serializer = new JsonSerializer();
            serializer.Serialize(writer, new { Value = obj });
            return ms.ToArray();
        }
    }
}

Anonymous class is used because BSON should start with a class or array. I have not tried to deserialize byte[] back to object and not sure if it works, but have tested the speed of conversion to byte[] and it completely satisfies my needs.


I'd rather use the expression "serialization" than "casting into bytes". Serializing an object means converting it into a byte array (or XML, or something else) that can be used on the remote box to re-construct the object. In .NET, the Serializable attribute marks types whose objects can be serialized.


You could use the built-in serialization tools in the framework and serialize to a MemoryStream. This may be the most straightforward option, but might produce a larger byte[] than may be strictly necessary for your scenario.

If that is the case, you could utilize reflection to iterate over the fields and/or properties in the object to be serialized and manually write them to the MemoryStream, calling the serialization recursively if needed to serialize non-trivial types. This method is more complex and will take more time to implement, but allows you much more control over the serialized stream.


What you're looking for is serialization. There are several forms of serialization available for the .Net platform


Using Encoding.UTF8.GetBytes is faster than using MemoryStream. Here, I am using NewtonsoftJson to convert input object to JSON string and then getting bytes from JSON string.

byte[] SerializeObject(object value) =>Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value));

Benchmark for @Daniel DiPaolo's version with this version

Method                    |     Mean |     Error |    StdDev |   Median |  Gen 0 | Allocated |
--------------------------|----------|-----------|-----------|----------|--------|-----------| 
ObjectToByteArray         | 4.983 us | 0.1183 us | 0.2622 us | 4.887 us | 0.9460 |    3.9 KB |
ObjectToByteArrayWithJson | 1.548 us | 0.0309 us | 0.0690 us | 1.528 us | 0.3090 |   1.27 KB |

public static class SerializerDeserializerExtensions
{
    public static byte[] Serializer(this object _object)
    {   
        byte[] bytes;
        using (var _MemoryStream = new MemoryStream())
        {
            IFormatter _BinaryFormatter = new BinaryFormatter();
            _BinaryFormatter.Serialize(_MemoryStream, _object);
            bytes = _MemoryStream.ToArray();
        }
        return bytes;
    }

    public static T Deserializer<T>(this byte[] _byteArray)
    {   
        T ReturnValue;
        using (var _MemoryStream = new MemoryStream(_byteArray))
        {
            IFormatter _BinaryFormatter = new BinaryFormatter();
            ReturnValue = (T)_BinaryFormatter.Deserialize(_MemoryStream);    
        }
        return ReturnValue;
    }
}

You can use it like below code.

DataTable _DataTable = new DataTable();
_DataTable.Columns.Add(new DataColumn("Col1"));
_DataTable.Columns.Add(new DataColumn("Col2"));
_DataTable.Columns.Add(new DataColumn("Col3"));

for (int i = 0; i < 10; i++) {
    DataRow _DataRow = _DataTable.NewRow();
    _DataRow["Col1"] = (i + 1) + "Column 1";
    _DataRow["Col2"] = (i + 1) + "Column 2";
    _DataRow["Col3"] = (i + 1) + "Column 3";
    _DataTable.Rows.Add(_DataRow);
}

byte[] ByteArrayTest =  _DataTable.Serializer();
DataTable dt = ByteArrayTest.Deserializer<DataTable>();

Like others have said before, you could use binary serialization, but it may produce an extra bytes or be deserialized into an objects with not exactly same data. Using reflection on the other hand is quite complicated and very slow. There is an another solution that can strictly convert your objects to bytes and vise-versa - marshalling:

var size = Marshal.SizeOf(your_object);
// Both managed and unmanaged buffers required.
var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
// Copy object byte-to-byte to unmanaged memory.
Marshal.StructureToPtr(your_object, ptr, false);
// Copy data from unmanaged memory to managed buffer.
Marshal.Copy(ptr, bytes, 0, size);
// Release unmanaged memory.
Marshal.FreeHGlobal(ptr);

And to convert bytes to object:

var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(bytes, 0, ptr, size);
var your_object = (YourType)Marshal.PtrToStructure(ptr, typeof(YourType));
Marshal.FreeHGlobal(ptr);

It's noticeably slower and partly unsafe to use this approach for small objects and structs comparing to your own serialization field by field (because of double copying from/to unmanaged memory), but it's easiest way to strictly convert object to byte[] without implementing serialization and without [Serializable] attribute.


How about something simple like this?

return ((object[])value).Cast<byte>().ToArray(); 

Alternative way to convert object to byte array:

TypeConverter objConverter = TypeDescriptor.GetConverter(objMsg.GetType());
byte[] data = (byte[])objConverter.ConvertTo(objMsg, typeof(byte[]));

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to object

How to update an "array of objects" with Firestore? how to remove json object key and value.? Cast object to interface in TypeScript Angular 4 default radio button checked by default How to use Object.values with typescript? How to map an array of objects in React How to group an array of objects by key push object into array Add property to an array of objects access key and value of object using *ngFor

Examples related to byte

Convert bytes to int? TypeError: a bytes-like object is required, not 'str' when writing to a file in Python3 How many bits is a "word"? How many characters can you store with 1 byte? Save byte array to file Convert dictionary to bytes and back again python? How do I get total physical memory size using PowerShell without WMI? Hashing with SHA1 Algorithm in C# How to create a byte array in C++? Converting string to byte array in C#