简体   繁体   English

C#中的动态字典用法

[英]Dynamic Dictionary usage in C#

I am using a Dynamic dictionary in C#. 我在C#中使用动态字典。 The problem I am facing is the behavior of TryGetMember which I am overriding in the dynamic dictionary class. 我面临的问题是TryGetMember的行为,我在动态字典类中重写。

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. 在这里,每当我们从外部引用一些键时,TryGetMember将在运行时被调用,但奇怪的是,binder的Name成员总是给出我们从外面引用的键,它总是解析写为字母字符的键名。

eg if the object of DynamicDictionary made as: 例如,如果DynamicDictionary的对象如下:

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 (ie a_binder.Name="somekey"). 现在这里发生的是“somekey”将成为a_binder的值(即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 (ie actually "Test" but it resolves not the value but actual variable name as key). 它应该被解析为a_binder.Name =“Test”,然后从动态字典中它将针对此键找到listOfStrings(即实际上是“Test”但它不是将值解析为实际变量名而是解析为键)。

Is there a way around this? 有没有解决的办法?

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 (ie "somekey"). 动态类型的工作方式完全符合它的意思 - 它不是设计用于检索变量的值并将其用作成员名称 - 它旨在使用您在源代码中使用的成员名称(即“somekey”)。

It sounds like you really don't need dynamic typing at all here - just use Dictionary<string,List<String>> as normal: 听起来你真的不需要动态类型 - 只需正常使用Dictionary<string,List<String>>

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. 这听起来好像你需要DynamicObject。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM