2010-08-12 58 views
0

我有一組消息,所有從消息派生,實現接口即時聊天:接口/繼承/委託設計問題

class Message : IMessage 
{ 
    public string example1; 
} 

class LogOnMessage : Message 
{ 
    public string password; 
} 

class LogOffMessage : Message 
{ 
    public string anotherExample; 
} 

我有一個信息系統,其中代理能夠檢測收到的消息,並根據消息的類型,運行形式的委託

void MyDelegate(IMessage msg) 

這是通過調用的處理程序登記功能這樣完成的:

RegisterHandler(typeof(LogoffMessage),handler) 

這種情況的實現是簡單類型的字典,每個條目是處理程序的列表:字典<類型,列表< MyDelegate>>

現在,這一切優秀的,但當然,處理器看起來像這樣:

void MyHandler(IMessage msg) 
{ 
    LogOffMessage lMsg = (LogOffMessage)msg; 
    string athrEx = lMsg.anotherExample; 

//Proceed with handling the logoff 
} 

現在,這裏有幾個問題。一個是你可能會嘗試將Msg轉換爲錯誤的類型。

另一種是,這是一個有點不雅有任何處理的前幾行解開一切,而不是處理這個樣子,我想這有

void MyDelegate(LogOffMessage msg) 

你會提出什麼建議?

我想也許代替類型的字典,其他一些結構可以用來保存不同的委託類型,使用泛型。因此,每種類型都會有一個MyDelegate < MsgType>列表。但目前還不清楚如何製作集合的集合,其中每種內部集合類型都不同。

回答

1

讓您的委託通用:

delegate void MessageHandler<T>(T message) where T : IMessage 

,讓您的RegisterHandler方法通用:

void RegisterHandler<T>(MessageHandler<T> handler) 

然後,用叫它:

RegisterHandler(handler); // Let type inference handle it 
RegisterHandler<LogOffMessage>(handler); // State type argument explicitly 

然後,當你通過獲取代理類型,您可以將其轉換爲正確的處理程序類型 - 即使它是c中的「不安全」看,ompiler的時候,你知道,你只添加了正確的處理程序到詞典:

// When you populate this, create the appropriate type of 
// `List<MessageHandler<T>>` based on the key 
private Dictionary<Type, object> handlerMap; 

void CallHandlers<T>(T message) where T : IMessage 
{ 
    object value; 
    if (handlerMap.TryGetValue(typeof(T), out value)) 
    { 
     List<MessageHandler<T>> handlers = (List<MessageHandler<T>>) value; 
     foreach (MessageHandler<T> handler : handlers) 
     { 
      handler(message); 
     } 
    } 
} 

需要注意的是另一種替代使用List<MessageHandler<T>>只是結合的代表並與最終多播委託在每個類型的地圖。