Potrzebuję przesyłać przez sieć dane o ściśle określonej strukturze, więc wymyśliłem sposób, żeby je przekonwertować do tablicy bajtów i z powrotem: z tablicy bajtów do obiektu. Przykładowy obiekt wygląda tak:
public class Message : ConvertableToBytes<Message>
{
public Message() {}
public Message(string text)
{
Text = text;
}
public string Text { get; }
}
Obiekt ten dziedziczy po klasie abstrakcyjnej, która implementuje m.in. dwie metody:
[Serializable]
public abstract class ConvertableToBytes<T> where T : new()
{
public byte[] PackToBytes()
{
// [...]
}
public static T Unpack(byte[] encodedData)
{
T result = new T();
// [...]
}
}
Jak się można domyślić, jedna pakuje obiekt w bajty, druga z bajtów wyciąga obiekt.
Działało to dobrze dopóki nie zacząłem bawić się w typy generyczne. Otóż chciałem zrobić taką metodę, która umożliwia wysłanie wiadomości i jednocześnie oczekiwanie na odpowiedź określonego typu T
. Metody SendMessageAwaitResponse
nie powinno interesować czym jest T
, ważne jedynie żeby T
miało funkcję Unpack
, która odpakowałaby odpowiedź wracającą z sieci.
public async Task<T> SendMessageAwaitResponse<T>(MessageNetworkLayer message)
{
ResponseStatus status = await SendMessage(message);
T response = T.Unpack(status.ImmadiateResponseBytes);
return response;
}
Normalnie w takich przypadkach zrobiłbym po prostu interfejs, dajmy na to IConvertableToBytes
i kazałbym mu implementować Unpack
, a w funkcji SendMessageAwaitResponse
określiłbym, że T
to IConvertableToBytes
. Tylko problem w tym, że Unpack
jest statyczne, a takich funkcji do interfejsu wrzucić się nie da.
Rozwiązaniem byłoby też zmienienie Unpack
na funkcję niestatyczną, ale nie podoba mi się ta opcja, bo wymuszałaby na programiście utworzenie ręcznie instancji rozpakowywanego obiektu i przekazanie go jako argument do Unpack
. Trochę niewygodne, więc zostawiam to jako ostateczność.
Ma ktoś pomysł jak by to rozwiązać?
iteredi