Home > C#, dynamic > DynamicObject Wrapper

DynamicObject Wrapper

Charlie Calvert started a discussion way back in January about a proposal to add dynamic lookup support to C# – a convenient way to write code that makes calls into objects of a type not known at compile time.

A number of people have suggested that for the dynamic case, the member access syntax should be made deliberately different to the usual dot syntax. There is a lot to be said for this. The big danger of this whole idea is that a radically less type-safe way of working will start to creep into programs that used to be type-safe, thus undoing some of the good work done by adding generics. But as long as the syntax makes this clear, it’s better to have convenient support than nothing at all, or else people will invent their own approach and it will probably be horrible.

I was thinking that maybe to underline the fact that the method name is really no more solid than a string, you could have the syntax mimic accessing items in a dictionary.

So instead of:


It would be:


It’s not a lot more typing, and it properly highlights the dynamic nature of what the code is doing. Any C# programmer would instantly get what it meant.

It also has an advantage that other syntaxes don’t – it allows me to pass a string variable if I want to.

But then I realised we can already do that today. Here’s a simplistic wrapper around any CLR object that provides that exact dictionary-like calling interface:

class DynamicObject
    private object m_target;

    public delegate object Member(params object[] args);

    public DynamicObject(object target)
        m_target = target;

    public Member this[object member]
        get { return args =>
            string name = member as string;
            if (name != null)
                // Try to find a method (TODO: overloading)
                MethodInfo m = m_target.GetType().GetMethod(name);

                if (m != null)
                    return m.Invoke(m_target, args);

                // Then try for an ordinary property
                PropertyInfo p = 

                if (p != null)
                    // No args implies get
                    if (args.Length == 0)
                        return p.GetValue(m_target, null);

                    // Otherwise, set - first arg is new value
                    p.SetValue(m_target, args[0], null);
                    return null;

            // Otherwise try indexer
            PropertyInfo i = m_target.GetType().GetProperty("Item");
            if (i != null)
                object[] memberArg = new object[] { member };

                if (args.Length == 0)
                    return i.GetValue(m_target, memberArg);

                i.SetValue(m_target, args[0], memberArg);
                return null;

            // Give up
            throw new InvalidOperationException(
                "No such member: " + name);
        }; }

The indexer simply returns a delegate that takes a variable number of arguments. It handles methods and properties, and gives them uniform syntax. It’s good for pretty much anything that the CLR can call through reflection. If there is no method or property with the specified name, it forwards the request on to the target object’s default indexer.

So suppose our mystery dynamic object has this implementation:

public class Universe
    public void LetThereBeLight()
        Console.WriteLine("And there was light!");

    public void CreateSexes(int n)
        Console.WriteLine("And there were " + n 
            + " of every creature, which was plenty");

    public int SpatialDimensions { get; set; }

    public string this[int day]
            switch (day)
                case 1: return "Heaven and Earth";
                case 2: return "Mammals";
                case 3: return "Fish";
                case 4: return "TV";
                case 5: return "Hi Def";
                case 6: return "Humans";

            return "Rested";

So if I know the type, I would write code like this in the usual way:

Universe u = new Universe();


u.SpatialDimensions = 3;

Debug.Assert(u.SpatialDimensions == 3);

Debug.Assert(u[3] == "Fish");

But we can wrap one in a DynamicObject and still use it fairly conveniently:

DynamicObject d = new DynamicObject(new Universe());



Debug.Assert((int)d["SpatialDimensions"]() == 3);
Debug.Assert((string)d[3]() == "Fish");

So do we really need a new language feature?

Categories: C#, dynamic Tags: ,
  1. paul
    August 3, 2008 at 12:15 am

    This is actually a pretty dang cool way to access any object dynamically. Thanks for posting!

  2. Daniel Earwicker
    August 11, 2008 at 8:30 am

    Thanks for saying so!

  3. Chris
    November 3, 2008 at 6:43 pm

    Actually that’s pretty similar to how Ruby works under-the-hood, if I’m not mistaken…

    basically all method calls and property gets/sets are forwarded to a “call(x)” method

  4. Steve Cooper
    November 4, 2008 at 1:53 pm

    I have a feeling that this won’t work with dynamic variables. Dynamic variables (objects implementing IDynamicObject) have exactly one method;

    public interface IDynamicObject
    MetaObject GetMetaObject(Expression parameter);

    This means reflection will always fail.

    For example, imagine a python list object, with methods like `append(item)` and `pop(number)`. Exposed as an IDynamicObject, calls to


    will return null because ‘append’ isn’t in the list of methods; only ‘GetMetaObject’ is.

    However, the syntax provided in C#4 allows for a cleverer interaction with the GetMetaObject which returns a delegate which, when called, invokes the `append` method. Allowing you to write;

    // c# code.

  5. int19h
    November 4, 2008 at 7:21 pm

    One thing you’re missing is that your solution really only covers the case of a “dynamic” receiver, while C# 4.0 will do dynamic calls for any combination of receiver and arguments that has at least one “dynamic” value. Also, it will do dynamic dispatch for operators applied to “dynamic” values, too.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: