Usm*_*man 3 .net c# dictionary dynamic
我在C#中使用动态字典.我面临的问题是TryGetMember的行为,我在动态字典类中重写.
这是动态字典的代码.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,每当我们从外部引用一些键时,TryGetMember将在运行时被调用,但奇怪的是,binder的Name成员总是给出我们从外面引用的键,它总是解析写为字母字符的键名.
例如,如果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
Run Code Online (Sandbox Code Playgroud)
现在这里发生的是"somekey"将成为a_binder的值(即a_binder.Name ="somekey").它应该被解析为a_binder.Name ="Test",然后从动态字典中它将针对此键找到listOfStrings(即实际上是"Test"但它不是将值解析为实际变量名而是解析为键).
有没有解决的办法?
动态类型的关键是使成员名称本身从源代码成员访问中得到解析.
动态类型的工作方式完全符合它的意思 - 它不是设计用于检索变量的值并将其用作成员名称 - 它旨在使用您在源代码中使用的成员名称(即"somekey").
听起来你真的不需要动态打字 - 只需Dictionary<string,List<String>>正常使用:
List<String> listOfStringsAsValue = dictionary[somekey];
Run Code Online (Sandbox Code Playgroud)
编辑:听起来你真的想要封装这样的字典:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
foo["first"].Add("value 1");
foo["second"].Add("value 2")
foo["first"].Add("value 1.1");
Run Code Online (Sandbox Code Playgroud)
如果您希望能够尝试获取列表而不创建新列表(如果它不存在),则可以添加一个方法来执行此操作.
这听起来好像你需要DynamicObject.
| 归档时间: |
|
| 查看次数: |
10479 次 |
| 最近记录: |