(将Dictionary转换为ILookup并不是很好:
How do I convert a Dictionary to a Lookup?

我想使用以下方法为我的容器类提供一个接口:

ILookup<Type, Entry> Query ( IEnumerable<QueryClause> query );


每个查询子句指定应从基础容器中取出哪种特殊条目以及哪些条目(以及更多详细信息)。

我的实现当前看起来像这样:

var result = new Dictionary<Type, List<Entry>>();

foreach(var clause in query)
{
    var clauseResult = FulfillClause(clause);
    result.Add(clause.Type, clauseResult);
}

return result.ToLookup(); // here it is


此方法是否有可能直接返回ILookup?不幸的是,它不支持yield return

最佳答案

我不太确定为什么首先要有字典。这对您有用吗?

return query.ToLookup(clause => clause.Type, clause => FullFillClause(clause));


它不符合ILookup<Type, Entry>接口,但是您提供的代码也不符合,所以我不确定您真正想要的是什么。

重新阅读问题后的尝试如下:

return query.SelectMany(c => FulfillClause(c).Select(r => new {Type=c.Type, Result=r}))
            .ToLookup(o => o.Type, o => o.Result);


这是@JonSkeet的链接答案的翻译。

为了在不知道所有类型和方法的细节的情况下进行测试,我使用了以下方法:

Func<List<int>> f = () => new List<int>() {1, 2, 3};
var query = new List<Type> {typeof (int), typeof (string)};

var l = query.SelectMany(t => f().Select(n => new {Type = t, Result = n}))
    .ToLookup(o => o.Type, o => o.Result);




如果控制所有代码,则可以重组其中一些代码以提高可读性:

return query.SelectMany(c => c.Fulfill())
            .ToLookup(res => res.Type, res => res.Value);

...
// You will need to create the ClauseFulfillment type yourself
public IEnumerable<ClauseFulfillment> FulFill()
{
   var results = // whatever FulfillClause does
   foreach(var r in results)
      yield return new ClauseFulfillment {Type = Type, Result = r};
}

08-20 02:29