Calling a method using dynamic with an out parameter

Go To StackoverFlow.com

3

I have a Dictionary<string,K> where K is a type that is loaded through reflection, I can't name K.

Unfortunately, I can't figure out how I'm supposed to use the TryGetValue method. I tried a couple of different things and they all lead to exceptions. What am I suppose to do?

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

I can write the more verbose if(dict.Contains("name")) d=dict["name"]

But I'd prefer if I could write the more concise TryGetValue approach.

Updated to include actual exception:

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& )
2012-04-05 00:45
by Michael B
If you don't know what K is anyway, why not just use IDictionary<string, object> instead? It will let you store objects of type K just fine and your method in the question would work - mellamokb 2012-04-05 01:03


3

You can't do that, because in .Net, variables used as ref and out parameters must match the type exactly. And a dynamic variable is actually an object variable at runtime.

But you could work around that by switching which parameter is out and which is the return value, although working with that would be less nice than normal 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;
    }
}

You could then call it like this:

dynamic dict = GetDictThroughMagic();
bool hasValue;
dynamic d = DictionaryHelper.TryGetValue(dict, "name", out hasValue);
2012-04-05 01:14
by svick
hmm for some reason I was hoping that dynamic would just kind of resolve this issue for me. I realize now why Ironpython turns your TryGetValue into a method that returns a tuple now - Michael B 2012-04-05 01:45
Yeah, returning a Tuple would work too. dynamic is not magic, it mostly obeys the same rules as normal C#, except they are resolved at runtime, not compile time - svick 2012-04-05 06:15


1

Why are you using a dynamic? Is this coming via an interop? I would suggest using a common abstraction that can be used here. Reflection does not mean dynamic, and this keyword is being thrown around in a static language in places that it is not needed. It was designed for interops...

More specific to your question: Here is what seems like a good answer. I do not believe that the cast can work here because it cannot cast up to type K.

2012-04-05 00:57
by Justin Pihony
I was trying an approach to make the code less ugly. Types are generated based on an xml doc at runtime. Once I have a K using dynamic is perfect. It's getting them out in the open that's the hard part - Michael B 2012-04-05 01:01
@MichaelB I still say that this is a bit of a hack for a design that needs refactored, but I updated my answer to a link to another SO question. Basically, you cannot cast up using dynamics...it seems - Justin Pihony 2012-04-05 01:07


0

I recently came across the similar error but came to a solution making all access to the dictionary dynamic.

Try

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

Hope this works out for you!

2013-12-11 14:37
by Min
Ads