2016-07-28 27 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