The following codes purpose is to generate an array of bytes that represents some user defined data. This array of bytes will later be used for sending over a network.
WelcomePacketWriter
is a concrete subclass of PacketWriter
. Subclasses of PacketWriter
can use methods provided by PacketWriter
to write to the list of bytes (methods such as WriteInt
, WriteString
and InsertShort
). The user can generate and get an array of bytes from a PacketWriter
subclass by calling the GetBytes
method which calls the abstract method GenerateBufferContent
(which should make changes to the buffer field) and converts the buffer field from a list to an array.
My main concern is that in PacketWriter.cs there is a lot of duplicate code for handling different types of data (GetBytes(short _value)
, GetBytes(int _value)
, GetBytes(float _value)
, etc...). I thought about using a generic method for GetBytes
, however as the BitConverter.GetBytes
method is not generic so I can't pass in a generic type. Using a switch statement based on the type in the generic method will still result in duplicate code and it may be unclear what types of data can be passed in without throwing an error.
PacketWriter.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace test
{
public abstract class PacketWriter
{
private List<byte> buffer;
internal PacketWriter()
{
buffer = new List<byte>();
}
public byte[] GetBytes()
{
GenerateBufferContent();
byte[] bytes = buffer.ToArray();
buffer.Clear();
return bytes;
}
protected abstract void GenerateBufferContent();
protected void Write(byte[] _value)
{
buffer.AddRange(_value);
}
protected void Insert(byte[] _value)
{
buffer.InsertRange(0, _value);
}
protected void WriteByte(byte _value)
{
Write(new byte[1] { _value });
}
protected void WriteShort(short _value)
{
Write(GetBytes(_value));
}
protected void WriteInt(int _value)
{
Write(GetBytes(_value));
}
protected void WriteFloat(float _value)
{
Write(GetBytes(_value));
}
protected void WriteBool(bool _value)
{
Write(GetBytes(_value));
}
protected void InsertByte(byte _value)
{
Insert(new byte[1] { _value });
}
protected void WriteString(string _value)
{
WriteInt(_value.Length);
Write(GetBytes(_value));
}
protected void InsertShort(short _value)
{
Insert(GetBytes(_value));
}
protected void InsertInt(int _value)
{
Insert(GetBytes(_value));
}
protected void InsertFloat(float _value)
{
Insert(GetBytes(_value));
}
protected void InsertBool(bool _value)
{
Insert(GetBytes(_value));
}
protected void InsertString(string _value)
{
Insert(GetBytes(_value));
InsertInt(_value.Length);
}
private byte[] GetBytes(short _value)
{
return BitConverter.GetBytes(_value);
}
private byte[] GetBytes(int _value)
{
return BitConverter.GetBytes(_value);
}
private byte[] GetBytes(float _value)
{
return BitConverter.GetBytes(_value);
}
private byte[] GetBytes(bool _value)
{
return BitConverter.GetBytes(_value);
}
private byte[] GetBytes(string _value)
{
return Encoding.ASCII.GetBytes(_value);
}
}
}
WelcomePacket.cs
namespace ConsoleAppTest
{
public class WelcomePacketWriter : PacketWriter
{
private string message;
private short clientId;
public WelcomePacketWriter(short _clientId, string _message)
{
message = _message;
clientId = _clientId;
}
protected override void GenerateBufferContent()
{
WriteShort(clientId);
WriteString(message);
}
}
}
BinaryWriter
? \$\endgroup\$