将不同值类型的数组转换为字节数组

这是我到目前为止所提出的,但它似乎不是最优的,任何关于更好方法的想法?

public void ToBytes(object[] data, byte[] buffer) { byte[] obytes; int offset = 0; foreach (object obj in data) { if (obj is string) obytes = System.Text.Encoding.UTF8.GetBytes(((string)obj)); else if (obj is bool) obytes = BitConverter.GetBytes((bool)obj); else if (obj is char) obytes = BitConverter.GetBytes((char)obj); // And so on for each valuetype Buffer.BlockCopy(obytes, 0, buffer, offset, obytes.Length); offset += obytes.Length; } } 

好吧,你可以有这样的地图:

 private static readonlyDictionary> Converters = new Dictionary>() { { typeof(string), o => Encoding.UTF8.GetBytes((string) o) }, { typeof(bool), o => BitConverter.GetBytes((bool) o) }, { typeof(char), o => BitConverter.GetBytes((char) o) }, ... }; public static void ToBytes(object[] data, byte[] buffer) { int offset = 0; foreach (object obj in data) { if (obj == null) { // Or do whatever you want throw new ArgumentException("Unable to convert null values"); } Func converter; if (!Converters.TryGetValue(obj.GetType(), out converter)) { throw new ArgumentException("No converter for " + obj.GetType()); } byte[] obytes = converter(obj); Buffer.BlockCopy(obytes, 0, buffer, offset, obytes.Length); offset += obytes.Length; } } 

您仍在为每种类型指定转换器,但它比if / elseforms更紧凑。

还有各种其他方法来构建字典,顺便说一句。 你可以这样做:

 private static readonly Dictionary> Converters = new Dictionary>(); static WhateverYourTypeIsCalled() { AddConverter(Encoding.UTF8.GetBytes); AddConverter(BitConverter.GetBytes); AddConverter(BitConverter.GetBytes); } static void AddConverter(Func converter) { Converters.Add(typeof(T), x => converter((T) x)); } 

我看到另一个答案建议二进制序列化。 我个人并不热衷于这样的“不透明”序列化方案。 我想知道数据的确切含义,这意味着我可以将其移植到其他平台。

但是,我会指出,你当前的方案没有给出任何类型的分隔符 – 例如,如果你有两个字符串,你就不知道哪个停止了,另一个停止了。 您也不存储类型信息 – 可能没问题,但可能不存在。 可变长度问题通常更为重要。 您可以考虑使用长度前缀方案,如BinaryWriter 。 实际上, BinaryWriter一般来说可能是一个更简单的解决方案。 您可能希望仍然拥有委托的映射,但要使它们采取BinaryWriter和值的操作。 然后,您可以通过reflection构建地图,或者只是硬编码的调用列表。

然后你只需初始化一个包装MemoryStreamBinaryWriter ,适当地写入每个值,然后在MemoryStream上调用ToArray来获得结果。

也许你应该考虑使用BinaryFormatter代替:

 var formatter = new BinaryFormatter(); var stream = new MemoryStream(); formatter.Serialize(stream, obj); byte[] result = stream.ToArray(); 

除此之外,还有一些非常好的序列化框架,如Google Protocol Buffers,如果你想避免重新发明轮子。

您可以使用StreamWriter写入内存流并使用其缓冲区:

  { byte[] result; using (MemoryStream stream = new MemoryStream()) { StreamWriter writer = new StreamWriter(stream); writer.WriteLine("test"); writer.WriteLine(12); writer.WriteLine(true); writer.Flush(); result = stream.GetBuffer(); } using(MemoryStream stream=new MemoryStream(result)) { StreamReader reader = new StreamReader(stream); while(! reader.EndOfStream) Console.WriteLine(reader.ReadLine()); } }