我正在嘗試編寫自動將數據包序列化並反序列化爲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。 –