以下代码旨在通过允许您在一组“getter”(数据检索客户端)上通用调用相同的选择器并将所有结果组合在一起来减少冗余代码。最终结果集是可等待的,允许系统在等待所有选择器完成时不会阻塞。
public async Task<T> GetBulkAsync<T>(Func<IGetter, Task<T>> selector) where T : IEnumerable<T>
{
Task<T>[] tasks = new Task<T>[this.getters.Count];
for (int i = 0; i < this.getters.Count; i++)
{
tasks[i] = selector(this.getters[i]);
}
T[] results = await Task.WhenAll(tasks);
return results.SelectMany<T, T>(r => r);
}
但是,我在这里的设计中出现了一个问题。在一种情况下,我只是想使用一个选择器来检索单个IData
,然后有时选择器将检索一个IEnumerable<IData>
或者可能是一个List<IData>
完全不同的东西。
我曾考虑过使用反射来处理具有通用集合的特殊情况,但这很麻烦,并且需要对我想要处理的每种类型的集合进行额外的工作。
我关心IEnumerable<IData>
(或真正关心IEnumerable<T>
)的主要原因是因为我想使用 Linq 的 SelectMany 来展平大结果集中的所有结果。如果每个选择器都返回一个IEnumerable<T>
,则需要将其缩减为一个IEnumerable<T>
,而不是一个IEnumerable<IEnumerable<T>>
。
除了编写几个不同的泛型方法,限制集合类型并且不使用反射之外,是否有解决这个问题的好方法?