2017-04-25 39 views
0

我正在寻找一种方法来快速和简单的实现这种模式的字节数组: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,但是对于这个简单的操作来说,它看起来太过头了。

你能帮我吗?谢谢。

回答

2

你在找什么是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. 
0

这看起来像协议缓冲的情况下,你可以看看在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); 
0

一个取巧的办法来实现这一目标是使用内置类的组合在.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();  
      }          
     } 

    }