2017-03-11 13 views
2

Dans mon programme, j'ai un PacketFactory qui construit des tampons prêts à être envoyés sur un NetworkStream. Comme vous pouvez le voir ci-dessous, cette méthode prend un paramètre court. Ce short est passé à BitConverter.GetBytes.Utilisez facilement toutes les surcharges qui existent sur BitConverter.GetBytes pour ma propre méthode

internal static class PacketFactory 
{ 
    internal static byte[] ToBuffer(PacketType type, short value) 
    { 
     byte[] packet = PacketTypeFactory.ToBuffer(type); 
     byte[] valueBytes = BitConverter.GetBytes(value); 

     byte[] buffer = new byte[packet.Length + valueBytes.Length]; 

     Array.Copy(packet, 0, buffer, 0, packet.Length); 
     Array.Copy(valueBytes, 0, buffer, packet.Length, valueBytes.Length); 

     return buffer; 
    } 
} 

Maintenant, mon problème:BitConverter.GetBytes a 10 surcharges. Je veux utiliser facilement toutes ces surcharges pour mon paramètre value dans la méthode ToBuffer.

Solution naïve: Créez toutes les surcharges qui existent également sur BitConverter.GetBytes et passez tout à une méthode interne. Y a-t-il une meilleure façon de résoudre cela?

internal static class PacketFactory 
{ 
    private static byte[] ToBuffer(PacketType type, byte[] value) 
    { 
     byte[] packet = PacketTypeFactory.ToBuffer(type); 

     byte[] buffer = new byte[packet.Length + value.Length]; 

     Array.Copy(packet, 0, buffer, 0, packet.Length); 
     Array.Copy(value, 0, buffer, packet.Length, value.Length); 

     return buffer; 
    } 

    internal static byte[] ToBuffer(PacketType type, short value) 
    { 
     return ToBuffer(type, BitConverter.GetBytes(value)); 
    } 
    internal static byte[] ToBuffer(PacketType type, int value) 
    { 
     return ToBuffer(type, BitConverter.GetBytes(value)); 
    } 
} 

Répondre

2

Utilisez une méthode générique qui accepte un Func:

internal static byte[] ToBuffer<T>(SocketType type, Func<T, byte[]> getBytes, T value) 
{ 
    byte[] packet = PacketTypeFactory.ToBuffer(type); 
    byte[] valueBytes = getBytes(value); 

    byte[] buffer = new byte[packet.Length + valueBytes.Length]; 

    Array.Copy(packet, 0, buffer, 0, packet.Length); 
    Array.Copy(valueBytes, 0, buffer, packet.Length, valueBytes.Length); 

    return buffer; 
} 

et l'appeler comme ça:

short shortValue = 5; 
PacketFactory.ToBuffer(SocketType.Raw, BitConverter.GetBytes, shortValue); 
// BitConverter.GetBytes(short) 

int intValue = 10; 
PacketFactory.ToBuffer(SocketType.Raw, BitConverter.GetBytes, intValue); 
// BitConverter.GetBytes(int) 

De cette façon, la surcharge correcte de BitConverter.GetBytes sera transmis à ToBuffer.

+1

Je dirais que ça rend l'API plus difficile à utiliser. Je ferais mieux de créer 10 surcharges que de forcer l'utilisateur de l'API à passer BitConverter.GetBytes à chaque fois. – Evk

+1

Thx. Cela fonctionnera bien, mais j'ai toujours besoin de passer 'BitConverter.GetBytes'. Ce serait OK si je pouvais déplacer le Func à la fin et utiliser BitConverter.GetBytes comme valeur par défaut, mais cela ne fonctionne pas, car les paramètres par défaut doivent être des constantes compiletime. –

+0

C'est la solution la plus élégante à laquelle je puisse penser. Le compilateur doit connaître la surcharge de 'BitConverter.GetBytes', il doit donc être utilisé dans la portée de la valeur. –