Я ищу способ добавить участников динамично к динамическому объекту. Хорошо, я предполагаю, что немного разъяснения необходимо...
Когда Вы делаете это:
dynamic foo = new ExpandoObject();
foo.Bar = 42;
Bar
свойство будет добавлено динамично во времени выполнения. Но код все еще относится "статически" к Панели (имя "Панель" трудно кодируется)... Что, если я хочу добавить свойство во времени выполнения, не зная его имя во время компиляции?
Я знаю, как сделать это с пользовательским динамическим объектом (я на самом деле вел блог об этом несколько месяцев назад), с помощью методов DynamicObject
класс, но как я могу сделать это с каким-либо динамическим объектом?
Я мог, вероятно, использовать IDynamicMetaObjectProvider
интерфейс, но я не понимаю, как использовать его. Например, какой аргумент должен, я передаю GetMetaObject
метод? (это ожидает Expression
)
И между прочим, как Вы выполняете отражение о динамических объектах? "Регулярное" отражение и TypeDescriptor
не показывайте динамическим участникам...
Любое понимание ценилось бы!
То, что вы хотите, подобно функциям Getattr / Setattr Python. Там нет встроенного эквивалентного способа сделать это в C # или VB.NET. Внешний слой DLR (который корабли с Ironpython и Ironruby в Microsoft.scripting.dll) включает в себя набор API-хостинга, который включает в себя API Objectoperations, который имеет методы GetMember / SetMember. Вы можете использовать их, но вам понадобится дополнительная зависимость от языка DLR и DLR.
Вероятно, самый простой подход будет создать вызовов с одним из существующих связующих C #. Вы можете получить код для этого, глядя на результат «Foo.bar = 42» в Ildasm или отражатель. Но простой пример этого будет:
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);