字典数组调用的Ienumerable Extension方法

时间:2010-10-12 10:58:31

标签: c# generics dictionary ienumerable linq-to-objects

我试图从字典保持数组中获取一个可枚举的集合。 或者我应该说,我正在尝试为我的字典对象编写扩展方法,该方法存储数组以在结果为null时返回IEnumerable项。

我使用dictionarys存储数组数据集(有速度原因),我在某些搜索点提取。提取的数据用于Linq查询,连接等,但是当数据集不存在时我会遇到问题。

返回一个空(0计数)行集将解决我的问题。到目前为止我所拥有的是(简化的程序代码)

 public class Supplier
 {
    public string ID {get;set}
    public string Name {get;set}
 }

 private sups[] = new Supplier[10];
 Dictionary<int,Supplier[]> dic = new Dictionary<int, Supplier[]>();
        dic.Add(1,sups[]);

 public static IEnumerable<Supplier> TryGetValue<Tkey>(this IDictionary<Tkey, Supplier[]> source, Tkey ItemKey)
    {
        Supplier[] foundList;
        IEnumerable<Supplier> retVal;

        if (source.TryGetValue(ItemKey, out foundList))
            {
                retVal = foundList.AsEnumerable();
            }
            else
            {
                retVal = new Supplier[0].AsEnumerable();
            }

        return retVal;
    }

//稍后在代码中有一些东西:

dic.TryGetValue(1).Count()

//or a linq join
from a in anothertable
join d in dic.TryGetValue(1) on a.ID equals d.ID

我试图实现的是一种通用的扩展方法,如下所示:

public static IEnumerable<T> TryGetValue<Tkey,TValue>(this IDictionary<Tkey, TValue> source, Tkey ItemKey)
{
   // same code...
   // returning  retVal = new T[0].AsEnumerable();
}

我一直在接近但从未完全在那里....我想保持扩展方法参数简单。它的传递让我一直不知所措。

如果有人可以提供帮助,请将您的反馈信息发送给我。

提前多多感谢!

1 个答案:

答案 0 :(得分:1)

编辑:类型推理的并发症。

这是一种方法,我们的想法是将字典值的类型限制为某事IEnumerable

不幸的是,类型推断似乎不适用于此签名(使用C#3测试),因此您必须明确指定泛型参数。

public static IEnumerable<TUnderlyingValue> GetValueOrEmpty<TKey, TUnderlyingValue, TValue>
              (this IDictionary<TKey, TValue> source, TKey key)
               where TValue : IEnumerable<TUnderlyingValue>
{

  if(source == null)
     throw new ArgumentNullException("source");

  TValue retVal;

  return source.TryGetValue(key, out retVal) ? retVal : Enumerable.Empty<TUnderlyingValue>;
}

<强>用法

var dict = new Dictionary<string, int[]>
           {
              { "foo", new[] { 6, 7, 8 } }
              { "bar", new[] { 1 } }
           };

var fooOrEmpty = dict.GetValueOrEmpty<string, int, int[]>("foo"); // { 6, 7, 8 }
var barOrEmpty = dict.GetValueOrEmpty<string, int, int[]>("bar"); // { 1 }
var bazOrEmpty = dict.GetValueOrEmpty<string, int, int[]>("baz"); // {   }

或者,我们可以使用2个通用参数而不受任何约束,但这会使字典类型的灵活性降低。在这种情况下,编译器会推断通用参数。

public static TUnderlyingValue[] GetValueOrEmpty<TKey, TUnderlyingValue>
         (this IDictionary<TKey, TUnderlyingValue[]> source, TKey key)                  
{

  if(source == null)
     throw new ArgumentNullException("source");

  TUnderlyingValue[] retVal;

  return source.TryGetValue(key, out retVal) ? retVal : new TUnderlyingValue[0];
}