gpt4 book ai didi

reflection - 动态添加成员到动态对象

转载 作者:行者123 更新时间:2023-12-01 17:55:40 27 4
gpt4 key购买 nike

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

当你这样做时:

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

Bar 属性将在运行时动态添加。但代码仍然“静态”引用 Bar(名称“Bar”是硬编码的)...如果我想在运行时添加属性而不在编译时知道其名称怎么办?

我知道如何使用自定义动态对象(我实际上 blogged about it 几个月前)使用 DynamicObject 类的方法来执行此操作,但是我如何使用 任何动态对象?

我可能可以使用IDynamicMetaObjectProvider接口(interface),但我不明白如何使用它。例如,我应该将什么参数传递给 GetMetaObject 方法? (它需要一个表达式)

顺便问一下,如何对动态对象执行反射? “常规”反射和 TypeDescriptor 不显示动态成员...

任何见解将不胜感激!

最佳答案

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

最简单的方法可能是使用现有的 C# 绑定(bind)器之一创建 CallSite。您可以通过查看 ildasm 或 Reflector 中“foo.Bar = 42”的结果来获取此代码。但一个简单的例子是:

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

关于reflection - 动态添加成员到动态对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2079870/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com