2017-04-25 43 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();  
      }          
     } 

    }