Неограниченный метод расширения для вызовов словарного массива - PullRequest
2 голосов
/ 12 октября 2010

Я пытаюсь получить перечислимую коллекцию из массива словаря.Или я должен сказать, что я пытаюсь написать метод расширения для своих объектов словаря, которые хранят массивы, чтобы возвращать элемент 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();
}

Я продолжаю приближаться, но никогда точно не ... Я хотел бы сохранить параметры метода расширения простыми.Это прохождение Т, которое продолжает меня ловить.

Если кто-то может помочь, пожалуйста, пришлите мне свой фид обратно.

большое спасибо заранее!

1 Ответ

1 голос
/ 12 октября 2010

РЕДАКТИРОВАТЬ: Осложнения с вводом типа.

Вот способ, идея состоит в том, чтобы ограничить тип значений словаря значением 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];
}
...