Dynamic Dictionary usage in C#

懵懂的女人 提交于 2019-12-22 11:10:05

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/3309191/dynamic-dictionary-usage-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!