问题描述
我在寻找一种方式来动态地添加成员到动态对象。好吧,我想一点需要澄清......
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);
这篇关于动态添加成员到动态对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!