2016-07-28 41 views
0

我正在嘗試創建一個事件/消息傳遞系統,訂閱者可以訂閱一般事件類型或特定事件類型。如何從字典鍵值查詢中列出值列表中的扁平列表?

我有一個事件類型的字典,其中包含所述類型的訂閱者列表,並且爲了將事件通知給訂閱者,我希望獲得這些列表中的所有訂閱的展開列表,其中訂閱是類型的等於或可從事件類型分配;換句話說,當字典鍵符合這個標準時。

如何獲得從字典的鍵(使用linq)查詢的列表項扁平列表?


我WIP代碼:

private Dictionary<Type, List<SomeEventDelegate>> subscriptions; 

// ...other code... 

public void Dispatch(SomeEvent someEvent) 
    { 
     // This should get the Key-Value pairs... How do I get a flattened list of all items in the values (which are lists themselves)? 
     List<SomeEventDelegate> subscribers = 
      from subscription in subscriptions 
      where subscription.Key.IsAssignableFrom(someEvent.GetType()) 
      select subscription; 

     //After I have the flattened list, I will dispatch the event to each subscriber here, in a foreach loop. 
    } 
+0

在一個側面說明,我不認爲你應該這樣做。您不需要像那樣管理訂閱者,這是內置於代表和事件中的。如果你需要更多的控制,那麼圍繞這個框架構建的框架就是正確的。 –

+0

@JeffMercado對於我的具體需求,訂閱者需要不知道事件源對象,並且只能知道訂閱這些事件的事件類型。 (它們可能會接收到觸發/源對象的引用,具體取決於事件類型;但這不是必要的或總體保證)---但是,我是C#事件的新手,可能會丟失可能影響或完全影響的關鍵信息改變這個要求或我的實施。如果您強烈懷疑是這種情況,請打電話給我聊天進一步討論!謝謝! – XenoRo

回答

2

SelectMany應該做的工作:

List<SomeEventDelegate> subscribers = 
    subscriptions.Where(kvp => 
     kvp.Key.IsAssignableFrom(someEvent.GetType()) 
    ).SelectMany(kvp => kvp.Value) 
    .ToList(); 

只能與鏈接,方法調用的語法做到這一點。你可以給它傳遞一個從參數中選擇一個IEnumerable<T>的lambda,並且當它將它從搜索中的每個項目收集的所有枚舉集合到一個大的扁平查詢中時,它將返回它。

+0

在鏈的末尾缺少'as List ',但除此之外,完美*完美*!非常感謝埃德! =) – XenoRo

+0

@AlmightyR哎呀!我認爲普通的ToList()應該這樣做,因爲Value是'IEnumerable '。 –

+0

更好! =)---(是的,我很新使用LINQ ...) – XenoRo

1

如果你喜歡的查詢語法(因此也懶得用什麼確切的方法),你爲什麼不只是繼續查詢:

List<SomeEventDelegate> subscribers = 
     (from subscription in subscriptions 
     where subscription.Key.IsAssignableFrom(someEvent.GetType()) 
     from subscriber in subscription.Value 
     select subscriber) 
     .ToList(); 
+0

雖然這會保持我原來代碼的語法風格,但它不像Ed的答案解決方案(IMO)那樣可讀。儘管如此,+1還是值得選擇的。 – XenoRo

相關問題