Dynamically adding members to a dynamic object

.net-4.0, c#-4.0, dynamic, dynamic-language-runtime, reflection

Solution

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.

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

Problem

I'm looking for a way to add members dynamically to an dynamic object. OK, I guess a little clarification is needed... When you do that : ``` dynamic foo = new ExpandoObject(); foo.Bar = 42; ``` 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 ? 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 ? 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`) And by the way, how do you perform reflection on dynamic objects ? "Regular" reflection and `TypeDescriptor` don't show the dynamic members... Any insight would be appreciated !

Original source