【问题标题】:Loop DynamicObject properties循环 DynamicObject 属性
【发布时间】:2011-01-27 09:13:57
【问题描述】:

我正在尝试了解 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 继承的各种现有对象。

需要反射吗?我一定是错过了什么……

【问题讨论】:

    标签: c# dynamicobject


    【解决方案1】:

    我相信您会对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 被声明为 public(除了其他 DynamicObject 成员),您需要使用反射来访问内部字典以轻松获取这些值(如果您不打算进行任何进一步的更改) .

    【讨论】:

    • 好的,谢谢,所以 - 对于继承 DynamicObject 并且不公开字典的现有对象 - 我没有办法(除了使用反射)来获取成员字典吗?
    • AFAIK 是的。您只能访问公共成员和 DynamicObject 类,其中成员访问通过各种方法解决。或者,您可以像 ExpandoObject 一样显式实现 IDictionary&lt;string, object&gt; 类,以简化此过程。
    • p.s.,对不起,我一开始掩盖了你的问题。我没有注意到您实际上是在实现示例代码。我在想,“没有DynamicDictionary 类......”:)
    • 答案中没有回答问题的部分正是我要找的。​​span>
    【解决方案2】:

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

    【讨论】:

    • 看起来不错-但我不想/不能更改我的类,并且“GetDynamicMemberNames() 是可选的,即从 DynamicObject 继承的类可以根据需要覆盖它,但如果不是基类中的函数被调用,返回一个空列表。”
    • 嗯,我明白了。然后我认为要么您需要使用 ExpandoObject,要么您需要自己实现它。
    【解决方案3】:

    我知道这个话题已经很老了,但是对于那些仍然想知道如何做的人来说,为什么不使用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;
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-17
      • 2021-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-03
      相关资源
      最近更新 更多