using System.Collections.Concurrent;
using System.Linq.Expressions;
public static void Main()
GenericBitConverter.GetBytes(1000).Dump();
GenericBitConverter.GetBytes(100.0).Dump();
GenericBitConverter.GetBytes(1000f).Dump();
GenericBitConverter.GetBytes(true).Dump();
GenericBitConverter.GetBytes(100M).Dump();
var objects = new object[]
foreach(var obj in objects)
GenericBitConverter.GetBytes(obj).Dump();
public class GenericBitConverter
public static byte[] GetBytes<T>(T value) { return Converter<T>.Convert(value);}
public static byte[] GetBytes(object value)
var type = value.GetType();
return cache.GetOrAdd(type, t =>
var par = Expression.Parameter(typeof(object));
return Expression.Lambda<Func<object, byte[]>>(Expression.Invoke(Expression.Field(null, typeof(Converter<>).MakeGenericType(type), "Convert"), Expression.Convert(par, type)), par).Compile();
private class Converter<T>
private static Func<T, byte[]> Create()
var par = Expression.Parameter(typeof(T));
return Expression.Lambda<Func<T, byte[]>>(Expression.Call(typeof(BitConverter), "GetBytes", Type.EmptyTypes, par), par).Compile();
catch (InvalidOperationException)
return v => throw new NotSupportedException(string.Format("Provided type {0} is not supported", typeof(T).FullName));
public static readonly Func<T, byte[]> Convert = Create();
private static ConcurrentDictionary<Type, Func<object, byte[]>> cache = new ConcurrentDictionary<System.Type, System.Func<object, byte[]>>();