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