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

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

问题描述

我正在寻找一种将成员动态添加到动态对象的方法.好的,我想需要澄清一下...

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(名称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 类的方法,但是我如何使用 任何动态对象?

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 方法?(它需要一个 Expression)

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

任何见解将不胜感激!

推荐答案

你想要的是类似于 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.

可能最简单的方法是使用现有的 C# 绑定程序之一创建 CallSite.您可以通过查看 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天全站免登陆