2012-04-05 5 views
3

У меня есть Dictionary<string,K>, где K представляет собой тип, который загружается через отражение, я не могу назвать К.Вызов метода с использованием динамическим с выводимым параметром

К сожалению, я не могу понять, как я предполагается использовать метод TryGetValue. Я попробовал пару разных вещей, и все они приводят к исключениям. Что я должен делать?

dynamic dict = GetDictThroughMagic(); 
dynamic d; 
bool hasValue = dict.TryGetValue("name",out d); 
bool hasValue = dict.TryGetValue("name",d); 

Я могу написать более подробный if(dict.Contains("name")) d=dict["name"]

Но я бы предпочел, если я мог бы написать более краткий TryGetValue подход.

Обновлено включает фактическое исключение:

Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: The 
best overloaded method match for 'System.Collections.Generic.Dictionary<string,K> 
.TryGetValue(string, out K)' has some invalid arguments 
    at CallSite.Target(Closure , CallSite , Object , String , Object&) 
+3

Если вы не знаете, что такое 'K', почему бы просто не использовать' IDictionary 'вместо этого? Это позволит вам хранить объекты типа 'K' просто отлично, и ваш метод в вопросе будет работать. – mellamokb

ответ

1

Почему вы используете dynamic? Это происходит через interop? Я бы предложил использовать общую абстракцию, которую можно использовать здесь. Отражение не означает динамическое, и это ключевое слово бросается на статическом языке в тех местах, где оно не требуется. Он был разработан для взаимодействия ...

Более конкретный вопрос: Here is what seems like a good answer. Я не верю, что литой может работать здесь, потому что он не может перебрасывать тип K.

+0

Я старался сделать код менее уродливым. Типы создаются на основе документа xml во время выполнения. Как только я использую динамику «K», она идеальна. Это вытаскивает их на открытом воздухе, это тяжелая часть. –

+0

@MichaelB Я все еще говорю, что это немного хак для дизайна, который нуждается в рефакторинге, но я обновил свой ответ на ссылку на другой вопрос SO. В принципе, вы не можете использовать динамику ... кажется. –

3

Вы не можете этого сделать, потому что в .Net переменные, используемые как параметры ref и out, должны точно соответствовать типу. А переменная dynamic на самом деле является переменной object во время выполнения.

Но вы могли бы работать вокруг этого путем переключения, какой параметр out и что возвращаемое значение, хотя работать с этим было бы менее приятно, чем обычный TryGetValue():

static class DictionaryHelper 
{ 
    public static TValue TryGetValue<TKey, TValue>(
     Dictionary<TKey, TValue> dict, TKey value, out bool found) 
    { 
     TValue result; 
     found = dict.TryGetValue(value, out result); 
     return result; 
    } 
} 

Вы могли бы назвать это так:

dynamic dict = GetDictThroughMagic(); 
bool hasValue; 
dynamic d = DictionaryHelper.TryGetValue(dict, "name", out hasValue); 
+0

hmm по какой-то причине я надеялся, что динамика просто решает эту проблему для меня. Теперь я понимаю, почему Ironpython превращает ваш TryGetValue в метод, который теперь возвращает кортеж. –

+0

Да, вернул бы «Кортеж». 'dynamic' не является магии, он в основном подчиняется тем же правилам, что и обычный C#, за исключением того, что они разрешены во время выполнения, а не время компиляции. – svick

0

Недавно я столкнулся с подобной ошибкой, но пришел к решению, обеспечивающему доступ к динамику словаря.

Попробуйте

dynamic dict = GetDictThroughMagic(); 
dynamic value = "wacka wacka"; // I renamed from 'd' and gave it a value 
dynamic key = "name"; 

if (dict.ContainsKey(key)) 
{ 
    dict[key] = value; 
} 

Надеется, что это работает для вас!

Смежные вопросы