2012-01-07 121 views
2

我正在使用一些.NET框架,它允許註冊類型爲Action<IMessage>的事件處理程序。通用事件處理

IMessage是接收所有消息的接口。

我希望能夠(以某種方式)註冊處理程序,瞭解收到的消息的具體類型,以便更徹底地記錄它。

事情與此類似:

manager.Register(SpecialHandler); 

public void SpecialHandler(SpecialMessage msg) 
{ 
    // log. 
} 
  • SpecialMessage是實現即時聊天類型。

這是不可能的,有沒有一種簡單的方法來做到這一點?

回答

3
// improved version of Travis Gockel's approach 
void Register<T>(Action<T> action, bool invokeOnTypeMismatch = false) 
    where T : IMessage 
{ 
    Action<IMessage> wrapped = (msg) => 
     { 
      if (msg is T) 
      { 
       action((T)msg); 
      } 
      else if (invokeOnTypeMismatch) 
      { 
       action(default(T)); 
      } 
     }; 

    // private Action<IMessage> method = delegate{}; 
    method += wrapped; 
} 
2
class MessageSystem 
{ 
    readonly Dictionary<Type, Action<IMessage>> handlers = new Dictionary<Type, Action<IMessage>>(); 

    public void Register<T>(Action<T> action) where T : IMessage 
    { 
     Action<IMessage> wrapped = (IMessage msg) => action((T)msg); 
     handlers[typeof(T)] = wrapped; 
    } 

    public void Invoke(IMessage msg) 
    { 
     handlers[msg.GetType()](msg); 
    } 
} 
+0

你打我吧! – siride 2012-01-07 23:15:35

+1

@ Travis Gockel:這裏的'method'是什麼? – Tigran 2012-01-07 23:21:08

+0

如果msg不能轉換爲T(即,如果註冊了兩個不同的專用處理程序),這將不起作用 – Nuffin 2012-01-07 23:22:24

1

您可以使用多態這裏

元代碼:

interface IMessage 
{ 
    void Handle() 
    ... 
} 

class MessageFoo : IMessage 
{ 
    void Handle() 
    { 
     //foo handle 
    } 
} 

class MessageBar : IMessage 
{ 
    void Handle() 
    { 
     //bar handle 
    } 
} 

而這正是你處理它們

class HandlingManager 
{ 
    void HandleMessage(IMessage m) 
    { 
     m.Handle(); //knows which concrete type 
    } 
} 
+0

我喜歡這種方法,但問題是現在你的消息的行爲與他們的類型有關。因此,以兩種不同的方式處理相同的信息是不可能的(取決於誰在處理它們)。 – 2012-01-07 23:32:39

+0

我不擁有IMessage的代碼,因此我不能以這種方式修改它。 – 2012-01-07 23:34:38

0

看看CSharpMessenger Extended

這是一個基於委託的C#事件系統。它使用泛型來實現靜態輸入。與其他消息傳遞系統(如CSharpEventManager)一樣,它允許事件生產者和事件消費者之間進行消息傳遞,而無需生產者或消費者相互瞭解。信使被實現爲靜態類,所以永遠不需要實例化一個信使對象。泛型的使用意味着參數可以是任何類型的,並且不侷限於特殊的Message類的子類 - 如果回調只需要一個浮點數然後提供一個浮點數。