是否有什么内在的错误
IDictionary<int, IEnumerable<string>>使用
ILookup<int, string>我更喜欢ILookup而不是IDictionary,因为它更“诚实”的界面和不变性。
但是,我发现ILookup无法保存空集合,因此包含空集合的键根本不存在。这是个问题,因为我还希望ILookup能够传递关于所有可能的键的信息(尽管其中一些键可能是空的),所以我可以这样做:
var statistics = from grouping in myLookup
select new {grouping.Key, grouping.Count()};它适用于可枚举的字典,但不幸的是,它不适用于ILookup。不可能有grouping.Count()==0的条目,就像IDictionary一样。正如约翰·斯基特所说,
在查找和字典之间还有一个重要的区别:如果您请求查找对应于它不知道的键的序列,它将返回一个空序列,而不是抛出一个异常。(查找所知道的密钥永远不会产生空序列。)
现在,如果ILookup允许空分组,又有什么问题呢?为了在这两个方面都发挥最好的作用,我将为ILookup添加Filter()扩展方法,该方法就是这样做的,但需要解决Linq不允许创建空IGroupings的问题(因此我必须实现自己的类),但我觉得可能是在违背Linq的设计原则。
发布于 2018-02-06 09:08:27
有两种选择:
1)您可以创建一个简单明了的EmptyLookup类,如下所示:
var empty = EmptyLookup<int, string>.Instance;
// ...
public static class EmptyLookup<TKey, TElement>
{
private static readonly ILookup<TKey, TElement> _instance
= Enumerable.Empty<TElement>().ToLookup(x => default(TKey));
public static ILookup<TKey, TElement> Instance
{
get { return _instance; }
}
}2)可以为空查找创建一个单例类。
public sealed class EmptyLookup<T, K> : ILookup<T, K>
{
private static readonly EmptyLookup<T, K> _instance
= new EmptyLookup<T, K>();
public static EmptyLookup<T, K> Instance
{
get { return _instance; }
}
private EmptyLookup() { }
public bool Contains(T key)
{
return false;
}
public int Count
{
get { return 0; }
}
public IEnumerable<K> this[T key]
{
get { return Enumerable.Empty<K>(); }
}
public IEnumerator<IGrouping<T, K>> GetEnumerator()
{
yield break;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
yield break;
}
}
then you can write code like this:
var x = EmptyLookup<int, int>.Instance;
/*The benefit of creating a new class is that you can use the "is" operator and check for type equality:*/
if (x is EmptyLookup<,>) {
// ....
}保持空分组是查找是没有错的,只是查找不支持它,因为它在Linq中是自然的。
您必须自己创建一个扩展方法。
https://stackoverflow.com/questions/48637498
复制相似问题