动态地将成员添加到动态对象 [英] Dynamically adding members to a dynamic object

查看:157
本文介绍了动态地将成员添加到动态对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种将动态添加到动态对象的方法。好的,我想有一点澄清是需要的...

I'm looking for a way to add members dynamically to an dynamic object. OK, I guess a little clarification is needed...

当你这样做:

dynamic foo = new ExpandoObject();
foo.Bar = 42;

属性将被动态添加运行。但是代码仍然是静态地到Bar(名称Bar是硬编码的)...如果我想在运行时添加一个属性,而不知道它在编译时的名称怎么办?

The Bar property will be added dynamically at runtime. But the code still refers "statically" to Bar (the name "Bar" is hard-coded)... What if I want to add a property at runtime without knowing its name at compile time ?

我知道如何使用自定义动态对象(我实际上 DynamicObject 类的方法,一个自定义动态对象/rel =nofollow noreferrer>几个月前)但是如何使用任何动态对象来执行?

I know how to do this with a custom dynamic object (I actually blogged about it a few months ago), using the methods of the DynamicObject class, but how can I do it with any dynamic object ?

我可以使用 IDynamicMetaObjectProvider 界面,但我不明白如何使用它。例如,我应该向 GetMetaObject 方法传递什么参数? (它期望一个表达式

I could probably use the IDynamicMetaObjectProvider interface, but I don't understand how to use it. For instance, what argument should I pass to the GetMetaObject method ? (it expects an Expression)

顺便说一句,你如何对动态对象执行反思? 常规反射和 TypeDescriptor 不显示动态成员...

And by the way, how do you perform reflection on dynamic objects ? "Regular" reflection and TypeDescriptor don't show the dynamic members...

任何见解将不胜感激!

Any insight would be appreciated !

推荐答案

你想要的是类似于Python的getattr / setattr函数。在C#或VB.NET中没有内置的等效方法。 DLR(与Microsoft.Scripting.dll中的IronPython和IronRuby一起运送)的外层包含一组托管API,其中包含一个具有GetMember / SetMember方法的ObjectOperations API。您可以使用它们,但您需要DLR和基于DLR的语言的额外依赖。

What you want is similar to Python's getattr/setattr functions. There's no built in equivalent way to do this in C# or VB.NET. The outer layer of the DLR (which ships w/ IronPython and IronRuby in Microsoft.Scripting.dll) includes a set of hosting APIs which includes an ObjectOperations API that has GetMember/SetMember methods. You could use those but you'd need the extra dependency of the DLR and a DLR based language.

可能最简单的方法是创建一个CallSite现有的C#绑定器。您可以通过查看ildasm或反射器中的foo.Bar = 42的结果来获取代码。但是一个简单的例子是:

Probably the simplest approach would be to create a CallSite w/ one of the existing C# binders. You can get the code for this by looking at the result of "foo.Bar = 42" in ildasm or reflector. But a simple example of this would be:

object x = new ExpandoObject();
CallSite<Func<CallSite, object, object, object>> site = CallSite<Func<CallSite, object, object, object>>.Create(
            Binder.SetMember(
                Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.None,
                "Foo",
                null,
                new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }
            )
        );
site.Target(site, x, 42);
Console.WriteLine(((dynamic)x).Foo);

这篇关于动态地将成员添加到动态对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆