我正在尝试编写自动将数据包序列化并反序列化为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));
}
}
现在,反序列化,我需要查找的Id在字典<字节,类型>,我在代码时注册了不同的ID。
这是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];
}
}
我正在寻找一种方法来自动生成每一个在编译时继承NetworkMessage
类的ID字节。我可以在运行时使用Reflection来做到这一点,但是我不知道我是否可以相信每个机器的Ids都是相同的,并且对于像这样的东西使用Reflection似乎有点过分。
或者,对于具有相同结果的不同方法的建议是值得欢迎的,我基本需要的是一个易于扩展的解决方案,其中“最终用户”只需要继承NetworkMessage
以便他们的代码与网络解决方案配合使用。
我可以100%确定分配的Ids每次运行时都是一样的,并且可以在每台机器/硬件设置上进行分配?如果在客户端上反序列化的消息是错误的,那就不太好了。 –
如果NetworkMessage实现上使用的属性指定应使用哪个消息ID来标识实现,那么是的。我将用示例属性和实现更新我的答案。 –
@MindWorX:在编译时生成消息ID的问题在于它并不能真正解决您正在尝试解决的问题。在重建代码时,不能保证消息ID不会改变(不像每次运行时那样糟糕),除非您在管理中进行构建。我发现一致的解决问题的唯一方法是为属性标识的每个类都设置固定ID。 –