【问题标题】:Ienumerable Extension method for dictionary array calls字典数组调用的可枚举扩展方法
【发布时间】:2010-10-12 10:58:30
【问题描述】:

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

我使用字典来存储数组数据集(这有速度的原因),我在某些搜索点提取了这些数据集。提取的数据用于 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();
}

我不断接近,但从来没有完全在那里....我想保持扩展方法参数简单。是 T 的过世让我一直在抓狂。

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

非常感谢!

【问题讨论】:

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


    【解决方案1】:

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

    这是一种方法,其想法是将字典值的类型限制为 anIEnumerableof something。

    不幸的是,类型推断似乎不适用于此签名(使用 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];
    }
    

    【讨论】:

    • 谢谢....我最终结合了一些答案并构建了这个似乎可以完成工作的扩展方法,感谢您的输入,包括温斯顿,因为我也使用了您的想法:跨度>
    • public static IEnumerable TryGetValue(this IDictionary source, Tkey ItemKey) { TValue foundList; if (source.TryGetValue(ItemKey, out foundList)) { return (IEnumerable) foundList; } 返回 Enumerable.Empty(); }
    猜你喜欢
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2013-08-11
    相关资源
    最近更新 更多