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

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

问题描述

我在寻找一种方式来动态地添加成员到动态对象。好吧,我想一点需要澄清......

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;

酒吧属性将在运行时动态增加。但是,code仍然是指静态向巴(名称为律师是硬codeD)......如果我想添加属性在运行时不知道它的名字在编译的时候怎么办?

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 类的方法,但我该怎么办它的任意的动态对象?

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 方法有什么说法? (预计的防爆pression

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...

任何有识之士将AP preciated!

Any insight would be appreciated !

推荐答案

你想要的是类似Python的GETATTR / SETATTR功能。有没有内置的等效办法做到这一点在C#或VB.NET。 DLR的外层(其中船舶瓦特/ IronPython和IronRuby的在Microsoft.Scripting.dll)包括一组托管的API,其中包括一个ObjectOperations API,它具有GetMember / SetMember方法。你可以使用这些,但你需要的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.

可能是最简单的方法是创建一个调用点瓦特/现有的C#粘合剂之一。您可以通过查看foo.Bar = 42的反汇编或反射的结果得到code这一点。但是,这是一个简单的例子是:

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天全站免登陆