Метод расширения словаря словарей - PullRequest
4 голосов
/ 26 мая 2009

Я пытаюсь написать метод расширения для вставки данных в словарь словарей, определенных следующим образом:

items=Dictionary<long,Dictionary<int,SomeType>>()

То, что я имею до сих пор:

    public static void LeafDictionaryAdd<TKEY1,TKEY2,TVALUE>(this IDictionary<TKEY1,IDictionary<TKEY2,TVALUE>> dict,TKEY1 key1,TKEY2 key2,TVALUE value)
    {
        var leafDictionary = 
            dict.ContainsKey(key1) 
                ? dict[key1] 
                : (dict[key1] = new Dictionary<TKEY2, TVALUE>());
        leafDictionary.Add(key2,value);
    }

но компилятору это не нравится. Утверждение:

items.LeafDictionaryAdd(longKey, intKey, someTypeValue);

дает мне ошибку вывода типа.

Для утверждения:

items.LeafDictionaryAdd<long, int, SomeType>(longKey, intKey, someTypeValue);

Я получаю "... не содержит определения для ... и лучшая перегрузка метода расширения имеет некоторые недопустимые аргументы.

Что я делаю не так?

Ответы [ 4 ]

8 голосов
/ 26 мая 2009

Некоторое изобретательское использование; -p

class SomeType { }
static void Main()
{
    var items = new Dictionary<long, Dictionary<int, SomeType>>();
    items.Add(12345, 123, new SomeType());
}

public static void Add<TOuterKey, TDictionary, TInnerKey, TValue>(
        this IDictionary<TOuterKey,TDictionary> data,
        TOuterKey outerKey, TInnerKey innerKey, TValue value)
    where TDictionary : class, IDictionary<TInnerKey, TValue>, new()
{
    TDictionary innerData;
    if(!data.TryGetValue(outerKey, out innerData)) {
        innerData = new TDictionary();
        data.Add(outerKey, innerData);
    }
    innerData.Add(innerKey, value);
}
2 голосов
/ 26 мая 2009

Я предполагаю, что это проблема ковариации / контравариантности. Ваша сигнатура метода ожидает IDictionary из IDcitionaries, но вы передаете ей IDictionary из словаря. Попробуйте использовать конкретный словарь вместо этого в своей подписи метода для внутреннего словаря.

2 голосов
/ 26 мая 2009

Попробуйте использовать конкретный тип:

public static void LeafDictionaryAdd<TKEY1,TKEY2,TVALUE>(this IDictionary<TKEY1, Dictionary<TKEY2,TVALUE>> dict,TKEY1 key1,TKEY2 key2,TVALUE value)

см. Dictionary<TKEY2,TVALUE> вместо IDictionary<TKEY2,TVALUE>

1 голос
/ 26 мая 2009

Если вы укажете IDictionary в списке параметров для метода Extension, тогда ваши предметы не будут соответствовать этому.

Либо измените свой добавочный номер на

public static void LeafDictionaryAdd<TKEY1,TKEY2,TVALUE>(
    this IDictionary<TKEY1, Dictionary<TKEY2,TVALUE>> dict,
    TKEY1 key1,
    TKEY2 key2,
    TVALUE value)

ИЛИ Попробуйте бросить свои вещи на

((IDictionary<long, IDictionary<int, YourType>>)items).LeafDictionaryAdd(l, i, o);
...