C#舒适的方式来构造不同的对象
问题描述:
我正在寻找一种方法来快速和简单的实现这种模式的字节数组:C#舒适的方式来构造不同的对象
MyByteArray mb = new MyByteArray();
mb.Add<byte>(bytevalue);
mb.Add<float>(floatvalue);
mb.Add<string>(str);
mb.Add<MyClass>(object);
,然后得到的byte []从MB到它发送一个字节的数据包通过RPC调用(在另一侧使用相同的技术解码)。
我找到了MemoryStream,但是对于这个简单的操作来说,它看起来太过头了。
你能帮我吗?谢谢。
答
你在找什么是BinaryWritter。但是它仍然需要一个Stream来纯粹的逻辑原因。唯一符合你需求的流是MemoryStream。
您是否害怕性能开销?您可以从现有的字节数组创建您的MemoryStream;
byte [] buffer = new byte[1024];
using (var memoryStream = new MemoryStream(buffer))
{
using (var binaryWriter = new BinaryWriter(memoryStream))
{
binaryWriter.Write(1.2F); // float
binaryWriter.Write(1.9D); // double
binaryWriter.Write(1); // integer
binaryWriter.Write("str"); // string
}
}
// buffer is filled with your data now.
答
这看起来像协议缓冲的情况下,你可以看看在protobuf-net。
首先,让我们来修饰类。
[ProtoContract]
class User
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
}
[ProtoContract]
class Message
{
[ProtoMember(1)]
public byte Type { get; set; }
[ProtoMember(2)]
public float Value { get; set; }
[ProtoMember(3)]
public User Sender { get; set; }
}
然后我们创建我们的消息。
var msg = new Message
{
Type = 1,
Value = 1.1f,
Sender = new User
{
Id = 8,
Name = "user"
}
};
现在,我们可以使用ProtoBuf的序列化器来完成我们所有的工作。
// memory
using (var mem = new MemoryStream())
{
Serializer.Serialize<Message>(mem, msg);
var bytes = mem.GetBuffer();
}
// file
using (var file = File.Create("message.bin")) Serializer.Serialize<Message>(file, msg);
答
一个取巧的办法来实现这一目标是使用内置类的组合在.NET
class Program
{
static void Main(string[] args)
{
Program program = new Program();
var listBytes = new List<byte>();
listBytes.Add(program.CastToBytes("test"));
listBytes.Add(program.CastToBytes(5));
}
注意 自定义对象,你必须在定义implicit operator
如何属性或所有对象应该转换
public byte[] CastToBytes<T>(T value)
{
//this will cover most of primitive types
if (typeof(T).IsValueType)
{
return BitConverter.GetBytes((dynamic)value);
}
if (typeof(T) == typeof(string))
{
return Encoding.UTF8.GetBytes((dynamic) value);
}
//for a custom object you have to define the rules
else
{
var formatter = new BinaryFormatter();
var memoryStream = new MemoryStream();
formatter.Serialize(memoryStream, value);
return memoryStream.GetBuffer();
}
}
}