2015-09-30 33 views
1

我正在嘗試創建一個原始/基本事件訂閱/發佈系統來進行實驗。如何查找擴展給定對象上基接口的所有接口?

我創建了一個基地IEventListener接口,然後在此基礎之上的通用IEventListener<T> : IEventListener接口,其中有一個功能OnEvent(T eventParam)

我然後創建實現IEventListener<string>IEventListener<int>

我認爲一個測試類通過傳遞它通過以下內容:

Dictionary<Type, List<object>> _listenersByType = new Dictionary<Type, List<object>>(); 

foreach(Type interfaceType in listener.GetType().GetInterfaces()) 
{ 
    if(interfaceType is IEventListener) 
    { 
     AddSubscriber(interfaceType.GetGenericTypeDefinition(), listener); 
    } 
} 

我可以創建一個查看事件類型的對象來將對象投射併發布到。但是,當通過。我看到它循環了所有的接口,我可以看到類型名稱是「IEventListener」,但條件永遠不是真的,並且永遠不會將我的偵聽器添加到字典中。

Pastebin of full code

回答

1

通過藉助該我不清楚(我在調試器戳左右),這樣可以修復它:

foreach(Type interfaceType in listener.GetType().GetInterfaces()) 
{ 
    if(interfaceType.GetInterfaces().Contains(typeof(IEventListener))) 
    { 
     AddSubscriber(interfaceType.GetGenericArguments()[0], listener); 
    } 
} 

,但我不能告訴你爲什麼必須檢查界面的界面。或者爲什麼我必須撥打interfaceType.GetGenericArguments()[0]而不是interfaceType.GetGenericTypeDefinition()

我的一部分感覺這個代碼很糟糕,我在這裏有一個設計問題。我永遠不會期望解決方案如此......醜陋。

0

你可以只問對象本身,如果它implemets接口。對於爲例我創建假類:

public class SListener<T> : IEventListener<T> 
{ 
public void OnEvent(T eventParam) 
    { 
    } 
} 

和它

var s = new SListener<string>(); 

對象,如果我問

bool t = (s is IEventListener); 

這是真的。

所以,你的訂閱mthod可能是這樣的:

public void Subscribe(object listener) 
{ 
    if(listener is IEventListener) 
    { 
     AddSubscriber(interfaceType.GetGenericTypeDefinition(), listener); 
    } 
} 
+0

這並不能幫助我分離出所有的'IEventListener 單曲,該對象實現雖然 – mGuv

+0

當然它的幫助,你只需要改變你的訂閱metgod:公共無效訂閱(對象監聽) { 如果(監聽器是IEventListener) AddSubscriber(interfaceType.GetGenericTypeDefinition(),listener); } } –

+0

我需要所有'IEventListener '接口,可能有多個,即, '公共類TestClass:IEventListener ,IEventListener ' - 當我訂閱一個對象時,它需要以兩個列表結束。一個用於'int'的'string'。 – mGuv