循环 DynamicObject 属性

发布于 2024-10-14 05:48:53 字数 690 浏览 2 评论 0原文

我试图理解 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 继承的各种现有对象。

是否需要反思?我一定是错过了什么……

I'm trying to understand the DynamicObject type. Found this MSDN article to be very consise and clear as how to create and use DynamicObject:

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

The article contains a simple DynamicDictionary class that inherits from DynamicObject.

Now I want to iterate over my dynamically created DynamicObject properties:

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;
}

Obviously that does not work. I want to learn how to do this without a change in my DynamicDictionary class, since I'm really trying to learn how to use this for all kinds of existing objects that inherits from DynamicObject.

Is Reflection needed? I must be missing something...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风苍溪 2024-10-21 05:48:53

我相信您会对 ExpandoObject类。 DynamicObject 类只是一个基础,您可以在其中提供所有逻辑。它显式实现了 IDictionary 接口,以便您可以访问它的属性或以这种方式添加新属性。

// 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 成员),因此您需要使用反射来访问内部字典以轻松获取这些值(如果您不打算进行任何进一步的更改)。

I believe you'd be interested in the ExpandoObject class. The DynamicObject class is just a base where you're meant to provide all the logic. It explicitly implements the IDictionary<string, object> interface so you can access it properties or add new ones that way.

// 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);

I had just realized that you are implementing the DynamicDictionary class and misunderstood your question. Sorry.

When used with a dynamic reference, you only have access to publicly exposed members. Since only Count is declared public (besides the other DynamicObject members), you'd need to use reflection in order to access the inner dictionary to easily get those values (if you don't intend to make any further changes).

我纯我任性 2024-10-21 05:48:53

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

I know this topic is pretty old but for those who are still wondering on how to do it, why not use the TryGetMember() method but construct a class that inherits the GetMemberBinder, like:

public class MyGetMemberBinder : GetMemberBinder
{
    public MyGetMemberBinder(string name, bool ignorecase) : base(name, ignorecase) { }
    public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)=>throw new NotImplementedException();
}

Then with 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;
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文