45

我试图了解 DynamicObject 类型。发现这篇 MSDN 文章对于如何创建和使用 DynamicObject 非常简洁明了:

http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx

本文包含一个简单的 DynamicDictionary 类,它继承自 DynamicObject。

现在我想遍历我动态创建的 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 继承的各种现有对象。

需要反射吗?我肯定错过了什么...

4

3 回答 3

51

我相信你会对这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课程并误解了您的问题。对不起。

与动态引用一起使用时,您只能访问公开的成员。由于 onlyCount被声明为公共(除了其他DynamicObject成员),因此您需要使用反射来访问内部字典以轻松获取这些值(如果您不打算进行任何进一步的更改)。

于 2011-01-27T09:25:19.077 回答
15

您是否尝试过 DynamicDictionary.GetDynamicMemberNames() 方法?- http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.getdynamicmembernames.aspx

于 2011-01-27T09:25:13.167 回答
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;
});
于 2020-07-07T17:43:56.140 回答