DynamicObject

I ran across this the other day when looking at some code from the Internet.  I hadn’t heard of DynamicObject before, so I thought I’d investigate.  The definition from MSDN states that it “Provides a base class for specifying dynamic behavior at run time. This class must be inherited from; you cannot instantiate it directly.”

You can think of it as something similar to the .NET Object class, except that it enables you to define which methods or properties can be performed at run time.

For other classes, you will get a compile time error when you’ve written code against a nonexistent method.  Classes that inherit from DynamicObject will not, but will be instead evaluated at run time.  If the dynamic class hasn’t implemented the method or coded for nonexistent methods, then a run time error will be thrown.

Here’s an example:

using System;
using System.Dynamic;

namespace DynamicObjectExample
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic test = new MyDynamicClass();

            int result = test.MyAdder(1, 2);

            Console.WriteLine("Result: " + result);
            Console.ReadLine();
        }
    }

    class MyDynamicClass : DynamicObject
    {

    }
}

The MyDynamicClass inherits from DynamicObject and is completely empty.  However, the Main method is calling a method called MyAdder which sonds like it adds two integer arguments.  When this code is compiled, there’s no errors, but when we run we get a “RunTimeBinderException was unhandled error” which states that “‘DynamicObjectExample.MyDynamicClass’ does not contain a definition for ‘MyAdder’.”

To add logic for situations where a method is invoked which doesn’t exist, the TryInvokeMember method can be overridden.

using System;
using System.Dynamic;

namespace DynamicObjectExample
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic test = new MyDynamicClass();

            int result = test.MyAdder(1, 2);

            Console.WriteLine("Result: " + result);
            Console.ReadLine();
        }
    }

    class MyDynamicClass : DynamicObject
    {
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            Console.WriteLine(binder.Name + "  Method not present in this  class ");
            result = 0;
            return true;
        }
    }
}

The result of the above is

“MyAdder Method not present in this class

Result: 0”

with no exceptions.  Now let’s see what happens when we actually implement the MyAdder method on MyDynamicClass.

using System;
using System.Dynamic;

namespace DynamicObjectExample
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic test = new MyDynamicClass();

            int result = test.MyAdder(1, 2);

            Console.WriteLine("Result: " + result);
            Console.ReadLine();
        }
    }

    class MyDynamicClass : DynamicObject
    {
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            Console.WriteLine(binder.Name + "  Method not present in this  class ");
            result = 0;
            return true;
        }

        public int MyAdder(int x, int y)
        {
            return x + y;
        }
    }
}

The result of the above will be “Result: 3” which is what we expect :).

TryGetMember and TrySetMember are other virtual members on DynamicClass that allow you to add logic for getting and setting properties that do not exist.

Advertisements

About Brian McKay
Software Architect

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: