C#中的动态字典用法
我在C#中使用动态字典。 我面临的问题是TryGetMember的行为,我在动态字典类中重写。
这是动态字典的代码。
class DynamicDictionary : DynamicObject { private IDictionary m_dictionary; public DynamicDictionary(IDictionary 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; } }
在这里,每当我们从外部引用一些键时,TryGetMember将在运行时被调用,但奇怪的是,binder的Name成员总是给出我们从外部引用的键,它总是解析写为字母字符的键名。
例如,如果DynamicDictionary的对象如下:
Dictionary<string,List> dictionaryOfStringVsListOfStrings; //here listOfStrings some strings list already populated with strings dictionaryOfStringVsListOfStrings.Add("Test", listOfStrings); dynamic dynamicDictionary_01 = new DynamicDictionary<List(dictionaryOfStringVsListOfStrings); string somekey = "Test"; //will be resolve at runtime List listOfStringsAsValue = dynamicDictionary_01.somekey
现在这里发生的是“somekey”将成为a_binder的值(即a_binder.Name =“somekey”)。 它应该被解析为a_binder.Name =“Test”,然后从动态字典中它将找到针对此键的listOfStrings(即实际上是“Test”但它不解析值而是将实际变量名称解析为键)。
有没有解决的办法?
动态类型的关键是使成员名称本身从源代码成员访问中得到解析。
动态类型的工作方式完全符合它的意思 – 它不是设计用于检索变量的值并将其用作成员名称 – 它旨在使用您在源代码中使用的成员名称(即“somekey”)。
这听起来你真的不需要动态类型 – 只需正常使用Dictionary
:
List listOfStringsAsValue = dictionary[somekey];
编辑:听起来你真的想要封装这样的字典:
public class Foo // TODO: Come up with an appropriate name :) { private readonly Dictionary> dictionary = new Dictionary>(); public List this[string key] { get { List list; if (!dictionary.TryGetValue(key, out list)) { list = new List (); dictionary[key] = list; } return list; } } }
然后你可以这样做:
foo["first"].Add("value 1"); foo["second"].Add("value 2") foo["first"].Add("value 1.1");
如果您希望能够尝试获取列表而不创建新列表(如果它不存在),则可以添加一个方法来执行此操作。
这听起来好像你需要DynamicObject。