Dynamic Dictionary usage in C#

18,792

The point of dynamic typing is to make the member names themselves get resolved from the source code member access.

Dynamic typing is working exactly as it's meant to here - it's not designed to retrieve the value of the variable and use that as the member name - it's designed to use the member name you used in your source code (i.e. "somekey").

It sounds like you really don't need dynamic typing at all here - just use Dictionary<string,List<String>> as normal:

List<String> listOfStringsAsValue = dictionary[somekey];

EDIT: It sounds like you actually want to encapsulate a dictionary like this:

public class Foo // TODO: Come up with an appropriate name :)
{
    private readonly Dictionary<string, List<string>> dictionary =
        new Dictionary<string, List<string>>();

    public List<string> this[string key]
    {
        get
        {
            List<string> list;
            if (!dictionary.TryGetValue(key, out list))
            {
                list = new List<string>();
                dictionary[key] = list;
            }
            return list;
        }
    }
}

Then you can do:

foo["first"].Add("value 1");
foo["second"].Add("value 2")
foo["first"].Add("value 1.1");

If you want to be able to attempt to fetch a list without creating a new one if it doesn't exist, you could add a method to do that.

It really doesn't sound like you need DynamicObject here.

Share:
18,792
Usman
Author by

Usman

Updated on July 04, 2022

Comments

  • Usman
    Usman almost 2 years

    I am using a Dynamic dictionary in C#. The problem I am facing is the behavior of TryGetMember which I am overriding in the dynamic dictionary class.

    Here's the code of dynamic dictionary.

    class DynamicDictionary<TValue> : DynamicObject
    {
        private IDictionary<string, TValue> m_dictionary;
    
        public DynamicDictionary(IDictionary<string, TValue> a_dictionary)
        {
            m_dictionary = a_dictionary;
        }
    
        public override bool TryGetMember(GetMemberBinder a_binder, out object a_result)
        {
            bool returnValue = false;
    
            var key = a_binder.Name;
            if (m_dictionary.ContainsKey(key))
            {
                a_result = m_dictionary[key];
                returnValue = true;
            }
            else            
                a_result = null;
    
            return returnValue;
        }
    }
    

    Here, TryGetMember will be called at runtime whenever we refer some key from outside, but it's strange that binder's Name member which always gives the key what we refer from outside, it always resolves the key name written as characters of alphabets.

    e.g. if the object of DynamicDictionary made as:

    Dictionary<string,List<String>> dictionaryOfStringVsListOfStrings; 
    
    //here listOfStrings some strings list already populated with strings
    dictionaryOfStringVsListOfStrings.Add("Test", listOfStrings); 
    dynamic dynamicDictionary_01 = new 
        DynamicDictionary<List<String>(dictionaryOfStringVsListOfStrings);
    
    string somekey = "Test";
    
    //will be resolve at runtime
    List<String> listOfStringsAsValue = dynamicDictionary_01.somekey 
    

    Now what happens here is "somekey" will become the value of a_binder (i.e a_binder.Name="somekey"). It should be resolved as a_binder.Name = "Test" and then from the dynamic dictionary it will locate listOfStrings against this key (i.e. actually "Test" but it resolves not the value but actual variable name as key).

    Is there a way around this?