Reputation: 6441
I am trying to create an event/messaging system where the subscribers can subscribe to general event types or specific event types.
I have a dictionary of event types containing lists of subscribers of said types, and, for notifying the events to the subscribers, I want to get a flattened list of all subscriptions within those lists, where the subscription is of a type that is equal to or assignable from the event's type; in other words, when the dictionary key meets that as a criteria.
How do I get a flattened list of the items of lists queried from a dictionary's keys (using linq)?
My WIP code:
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.
}
Upvotes: 0
Views: 161
Reputation: 37059
SelectMany should do the job:
List<SomeEventDelegate> subscribers =
subscriptions.Where(kvp =>
kvp.Key.IsAssignableFrom(someEvent.GetType())
).SelectMany(kvp => kvp.Value)
.ToList();
You can only do it with the chained-method-call syntax. You pass it a lambda that selects an IEnumerable<T>
from the parameter, and as it goes it merges all the enumerables that it collects from each item in the query into one big flat query, which it returns.
Upvotes: 2
Reputation: 205589
If you prefer the query syntax (hence don't bother what exact method is used), why don't you just continue your query:
List<SomeEventDelegate> subscribers =
(from subscription in subscriptions
where subscription.Key.IsAssignableFrom(someEvent.GetType())
from subscriber in subscription.Value
select subscriber)
.ToList();
Upvotes: 1