Creating Your Own Custom Dynamic C# Classes

C# provides pre-supplied dynamic types such as the ExpandoObject. It is also possible to create new dynamic types or add dynamic capabilities to existing custom classes.

One of the core interfaces that enables dynamic behaviour is the IDynamicMetaObjectProvider interface. Whilst this interface can be implemented, an easier way to create a custom dynamic class is to inherit from DynamicObject class.

The DynamicObject base class provides a number of virtual methods that allow an instance of the derived class to respond to dynamic operations such as getting or setting the value of a dynamically added property or invocation of a dynamic method.

The following simple example allows adding of arbitrary dynamic properties at runtime. The class overrides the TrySetMember and TryGetMember virtual methods to provide the behaviour. Notice that these methods have a binder parameter that gives information about the dynamic operation that is being attempted, such as the name of the property (binder.Name). Also note that the methods return a Boolean value to indicate to the runtime whether the dynamic operation succeeded.

using System.Collections.Generic;
using System.Dynamic;
using System.Text;

namespace CustomDynamic
{
    class MyDynamicClass : DynamicObject
    {
        private readonly Dictionary<string, object> _dynamicProperties = new Dictionary<string, object>(); 

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            _dynamicProperties.Add(binder.Name, value);

            // additional error checking code omitted

            return true;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            return _dynamicProperties.TryGetValue(binder.Name, out result);
        }

        public override string ToString()
        {
            var sb = new StringBuilder();

            foreach (var property in _dynamicProperties)
            {
                sb.AppendLine($"Property '{property.Key}' = '{property.Value}'");
            }

            return sb.ToString();
        }
    }
}

At runtime, if the instance of the class is declared as dynamic, arbitrary properties can be set as the following simple console application demonstrates:

using System;

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

            // Need to declare as dynamic, the following cause compilation errors:
            //      MyDynamicClass d = new MyDynamicClass();
            //      var d = new MyDynamicClass();

            // Dynamically add properties
            d.Name = "Sarah"; // TrySetMember called with binder.Name of "Name"
            d.Age = 42; // TrySetMember called with binder.Name of "Age"

            Console.WriteLine(d.Name); // TryGetMember called
            Console.WriteLine(d.Age); // TryGetMember called

            Console.ReadLine();
        }
    }
}

To learn more about how C# makes dynamic possible, some potential use cases, and more detail on implementing custom types check out my Dynamic C# Fundamentals Pluralsight course.

Comments (5) -

  • Chris Cooper

    6/16/2016 10:04:12 AM | Reply

    This will come in useful, thanks.

  • Satish Harnol

    6/27/2016 3:08:45 PM | Reply

    This is cool.  One problem I found in 'TrySetMember' is you can not overwrite value for same field. Means fields of class are read only. Below is my version of same method

    public override bool TrySetMember(SetMemberBinder binder, object value)
      {
        if (_dynamicProperties.Keys.Contains(binder.Name))
        {
          _dynamicProperties[binder.Name] = value;
        }
        else
        {
          _dynamicProperties.Add(binder.Name, value);
        }

        // additional error checking code omitted

        return true;
      }

  • Himanshu

    11/7/2016 6:38:23 AM | Reply

    Hi  How can I add  Attributes to properties here(   like - [FieldFixedLength(30)] for Name ). Also, above article is applicable to compile time only, if I wanted to add properties at runtime how can achieve so ( apart from ObjectAccessor.Create)

  • Glauco Basilio

    12/21/2016 4:27:19 PM | Reply

    Hi, very useful post. Just one sugestion if you wana dynamic members to be Json.Net serialized just override GetDynamicMemberNames like this:

    public override IEnumerable<string> GetDynamicMemberNames()
    {
          return _dynamicProperties.Keys;
    }

Add comment

Loading