Я пытаюсь написать сетевой код, который автоматически сериализует и десериализует пакет в NetworkMessage
.
Вот код для NetworkMessage
public abstract class NetworkMessage : ISerializable
{
public readonly NetworkClient Client;
protected NetworkMessage(NetworkClient client)
{
this.Client = client;
}
public abstract void GetObjectData(SerializationInfo info, StreamingContext context);
}
А вот коддля образца NetworkMessageText
public class NetworkMessageText : NetworkMessage
{
public static readonly Byte Id = 0x01;
public readonly String Message;
public NetworkMessageText(NetworkClient client, String message)
: base(client)
{
this.Message = message;
}
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("message", this.Message, typeof(String));
}
}
Теперь, чтобы десериализовать это, мне нужно будет найти идентификатор в словарегде я зарегистрировал разные идентификаторы во время кода.
Это класс NetworkMessagesIds
, который делает это для меня
public static class NetworkMessageIds
{
private static readonly Dictionary<Type, Byte> TypeIdDictionary = new Dictionary<Type, Byte>();
private static readonly Dictionary<Byte, Type> IdTypeDictionary = new Dictionary<Byte, Type>();
static NetworkMessageIds()
{
TypeIdDictionary.Add(typeof(NetworkMessageText), NetworkMessageText.Id);
IdTypeDictionary.Add(NetworkMessageText.Id, typeof(NetworkMessageText));
}
public static Byte IdFromType(Type type)
{
return TypeIdDictionary[type];
}
public static Type TypeFromId(Byte id)
{
return IdTypeDictionary[id];
}
}
То, что я ищу, это способавтоматически генерировать байт Id для каждого класса, который наследует NetworkMessage
во время компиляции.Я мог бы сделать это во время выполнения, используя Reflection, но тогда я не знаю, могу ли я доверять, чтобы идентификаторы были одинаковыми каждый раз для каждой машины, и использование Reflection кажется немного чрезмерным для чего-то подобного.
В качестве альтернативы приветствуются предложения по различным подходам с одним и тем же результатом, в чем я в основном нуждаюсь - это легко расширяемое решение, где «конечному пользователю» нужно только унаследовать NetworkMessage
, чтобы его код работал с сетевым решением.*