2017-04-25 4 views
0

Je cherche un moyen de rapide et la mise en œuvre simple de ce paradigme:C# façon confortable pour construire tableau d'octets à partir d'objets différents

MyByteArray mb = new MyByteArray(); 
mb.Add<byte>(bytevalue); 
mb.Add<float>(floatvalue); 
mb.Add<string>(str); 
mb.Add<MyClass>(object); 

Et puis obtenir byte [] de mb pour l'envoyer comme un paquet d'octets via appel RPC (à décoder de l'autre côté en utilisant la même technique).

J'ai trouvé MemoryStream, mais il semble trop frais pour cette opération simple.

Pouvez-vous m'aider? Je vous remercie.

Répondre

2

Que recherchez-vous est BinaryWritter. Mais il a encore besoin d'un Stream pour écrire pour une raison purement logique. Et le seul flux qui correspond à votre besoin est MemoryStream.

Avez-vous peur des frais généraux liés aux performances? Vous pouvez créer votre MemoryStream à partir d'un tableau d'octets existant;

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

Cela ressemble le cas pour Buffers Protocole, vous pouvez regarder à protobuf-net.

Tout d'abord, décorons les classes.

[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; } 
} 

Ensuite, nous créons notre message.

var msg = new Message 
{ 
    Type = 1, 
    Value = 1.1f, 
    Sender = new User 
    { 
    Id = 8, 
    Name = "user" 
    } 
}; 

Et maintenant, nous pouvons utiliser le sérialiseur de ProtoBuf pour faire tout notre travail.

// 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

Une façon délicate pour y parvenir est d'utiliser une combinaison de classe builtin dans .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));   
     } 

Remarque pour un objet personnalisé, vous devez définir un implicit operator sur la façon dont les propriétés ou tout l'objet devrait être converti

 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();  
      }          
     } 

    }