【问题标题】:How to get flattened list from dictionary key query where values are lists?如何从值是列表的字典键查询中获取扁平列表?
【发布时间】:2016-07-29 03:57:30
【问题描述】:

我正在尝试创建一个事件/消息传递系统,订阅者可以在其中订阅一般事件类型或特定事件类型。

我有一个事件类型字典,其中包含所述类型的订阅者列表,并且为了将事件通知给订阅者,我想获取这些列表中所有订阅的扁平列表,其中订阅的类型为等于或可从事件的类型分配;换句话说,当字典键符合条件时。

如何获取从字典键中查询的列表项的扁平列表(使用 linq)?


我的在制品代码:

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.
    }

【问题讨论】:

  • 附带说明,我认为您根本不应该这样做。您不需要像这样管理订阅者,这是内置在委托和事件中的。如果您需要更多控制权,可以使用围绕此构建的框架来解决问题。
  • @JeffMercado 对于我的特定需求,订阅者需要不知道事件源对象,并且必须只知道事件类型才能订阅这些事件。 (他们可能会收到对触发/源对象的引用,具体取决于事件类型;但这不是必需的或总体上保证的)---但是,我是 C# 事件的新手,可能缺少可能影响或完全影响的关键信息更改此要求或我的实施。如果您强烈怀疑是这种情况,请在聊天中给我打电话进一步讨论!谢谢!

标签: c# linq dictionary


【解决方案1】:

SelectMany 应该可以完成这项工作:

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

您只能使用链式方法调用语法来做到这一点。你向它传递一个 lambda,它从参数中选择一个 IEnumerable&lt;T&gt;,然后它将从查询中的每个项目收集的所有枚举合并到一个大的平面查询中,然后返回。

【讨论】:

  • 在链的末端缺少as List&lt;SomeEventDelegate&gt;,但除此之外,完美地工作!非常感谢埃德! =)
  • @AlmightyR 哎呀!我认为普通的 ToList() 应该这样做,因为 Value 是 IEnumerable&lt;SomeEventDelegate&gt;
  • 更好! =) ---(是的,我对使用 linq 很陌生...)
【解决方案2】:

如果您更喜欢查询语法(因此不必担心使用的确切方法),为什么不继续查询:

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

【讨论】:

  • 虽然这将保持我原始代码的语法风格,但它不像 Ed 的答案解决方案 (IMO) 那样可读。尽管如此,替代方案值得 +1。
猜你喜欢
  • 1970-01-01
  • 2015-09-05
  • 1970-01-01
  • 2013-08-29
  • 1970-01-01
  • 2022-06-21
  • 1970-01-01
  • 2022-12-07
相关资源
最近更新 更多