2009-05-26 3 views
4

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

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); 

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

Что я делаю неправильно. ?

+0

Это работает для меня, когда я пытался это: | – mquander

+0

Argh. Вот это боль. Нет модов вообще? – spender

+1

О, у меня были мои «предметы», объявленные как IDictionary из словарей - это, вероятно, ключевое различие. – mquander

ответ

8

Некоторые изобретательский родовое использование ;-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); 
} 
+0

+1 Для умных. :) –

+0

Lovely. Благодарю. – spender

+0

Это самый крутой код, который я видел ... хорошая работа – CSharpAtl

2

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

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>

2

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

+0

Это не догадка - вы на 100% правильны. –

1

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

Либо измените расширение на

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); 
Смежные вопросы