我正在尝试理解DynamicObject类型。发现这篇MSDN文章非常简洁明了,如何创建和使用DynamicObject:
http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx
本文包含一个继承自DynamicObject的简单DynamicDictionary类。
现在我想迭代我动态创建的DynamicObject属性:
dynamic d = new DynamicDictionary();
d.Name = "Myname";
d.Number = 1080;
foreach (var prop in d.GetType().GetProperties())
{
Console.Write prop.Key;
Console.Write prop.Value;
}
显然这不起作用。我想学习如何在不改变DynamicDictionary类的情况下做到这一点,因为我真的想学习如何将它用于从DynamicObject继承的各种现有对象。
需要反思吗?我一定错过了什么......
答案 0 :(得分:47)
我相信你对ExpandoObject
课感兴趣。 DynamicObject
类只是您打算提供所有逻辑的基础。它显式实现了IDictionary<string, object>
接口,因此您可以访问它的属性或以这种方式添加新属性。
// declare the ExpandoObject
dynamic expObj = new ExpandoObject();
expObj.Name = "MyName";
expObj.Number = 1000;
// print the dynamically added properties
foreach (KeyValuePair<string, object> kvp in expObj) // enumerating over it exposes the Properties and Values as a KeyValuePair
Console.WriteLine("{0} = {1}", kvp.Key, kvp.Value);
// cast to an IDictionary<string, object>
IDictionary<string, object> expDict = expObj;
// add a new property via the dictionary reference
expDict["Foo"] = "Bar";
// verify it's been added on the original dynamic reference
Console.WriteLine(expObj.Foo);
我刚刚意识到你正在实施DynamicDictionary
课程并误解了你的问题。遗憾。
与动态参考一起使用时,您只能访问公开公开的成员。由于只有Count
被声明为公共(除了其他DynamicObject
成员),因此您需要使用反射来访问内部字典以轻松获取这些值(如果您不打算生成任何进一步的变化)。
答案 1 :(得分:14)
您是否尝试过DynamicDictionary.GetDynamicMemberNames()方法? - http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.getdynamicmembernames.aspx
答案 2 :(得分:0)
我知道这个主题已经很老了,但是对于那些仍然想知道如何做到这一点的人,为什么不使用TryGetMember()
方法,而是构造一个继承GetMemberBinder
的类,例如:>
public class MyGetMemberBinder : GetMemberBinder
{
public MyGetMemberBinder(string name, bool ignorecase) : base(name, ignorecase) { }
public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)=>throw new NotImplementedException();
}
然后使用LINQ:
Dictionary<string, object> AsStandardDictionary = DynamicDictionary.GetDynamicMemberNames().ToDictionary(x => x, y =>
{
if(DynamicDictionary.TryGetMember(new MyGetMemberBinder(y, false), out var result))
return result;
else
return null;
});