SoFunction
Updated on 2025-03-07

Detailed explanation of C# dynamic objects (dynamics) (implementing dynamics of methods and attributes)

The properties of dynamic objects in C# are relatively simple to implement. If you want to implement dynamic methods such as dynamic languages, it is more difficult, because dynamic objects, extension methods, and anonymous methods cannot be used directly. Here we still use objects and delegates to simulate the implementation of this dynamic method, which looks a bit like a JavaScript object:

1) Define a delegate, the number of parameters is variable, and the parameters are all object types: the delegate here has a dynamic parameter, which represents the dynamic object itself that calls the delegate.

public delegate object MyDelegate(dynamic Sender, params object[] PMs);

2) Define a delegated reprint object, because dynamic objects cannot be directly used with anonymous methods, here are objects to host:

public class DelegateObj
  {
    private MyDelegate _delegate;

    public MyDelegate CallMethod
    {
      get { return _delegate; }
    }
    private DelegateObj(MyDelegate D)
    {
      _delegate = D;
    }
    /// <summary>
    /// Construct the delegate object so that it looks a bit like a javascript definition.    /// </summary>
    /// <param name="D"></param>
    /// <returns></returns>
    public static DelegateObj Function(MyDelegate D)
    {
      return new DelegateObj(D);
    }
  }

3) Define a dynamic object:

public class DynObj : DynamicObject
  {
    //Save the attribute value dynamically defined by the object    private Dictionary<string, object> _values;
    public DynObj()
    {
      _values = new Dictionary<string, object>();
    }
    /// <summary>
    /// Get attribute value    /// </summary>
    /// <param name="propertyName"></param>
    /// <returns></returns>
    public object GetPropertyValue(string propertyName)
    {
      if (_values.ContainsKey(propertyName) == true)
      {
        return _values[propertyName];
      }
      return null;
    }
    /// <summary>
    /// Set attribute value    /// </summary>
    /// <param name="propertyName"></param>
    /// <param name="value"></param>
    public void SetPropertyValue(string propertyName,object value)
    {
      if (_values.ContainsKey(propertyName) == true)
      {
        _values[propertyName] = value;
      }
      else
      {
        _values.Add(propertyName, value);
      }
    }
    /// <summary>
    /// Implement the method of dynamic object attribute member access to get the value of the specified attribute returned    /// </summary>
    /// <param name="binder"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
      result = GetPropertyValue();
      return result == null ? false : true;
    }
    /// <summary>
    /// Method to implement dynamic object attribute value setting.    /// </summary>
    /// <param name="binder"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
      SetPropertyValue(, value);
      return true;
    }
    /// <summary>
    /// The actual code executed when dynamic method invocation of dynamic objects    /// </summary>
    /// <param name="binder"></param>
    /// <param name="args"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
      var theDelegateObj = GetPropertyValue() as DelegateObj;
      if (theDelegateObj == null ||  == null)
      {
        result = null;
        return false;
      }
      result = (this,args);
      return true;
    }
    public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
    {
      return (binder, args, out result);
    }
  }

Application test code:

dynamic theObj = new DynObj();
       = "this is a test";//Dynamic attributes      //Dynamic method, you cannot define parameters here. You can use any multiple parameters when calling. You can only handle the specific parameter types and meanings carefully by yourself.       = ((s, pms) =>
      {
        if (pms != null &&  > 0)
        {
          (pms[0].ToString() + ":" + );
        }
        else
        {
          ();
        }
        return null;
      }
      );
      
("hello");

Although it seems that Js defines object methods above, since C# is a static language, the dynamic simulation mechanism provided is still limited and seems to be dynamic, but all value storage and methods need to be written by yourself to process.

The above code is tested OK on vs2010, windows 2008 server, framework 4.0.

The above detailed explanation of C# dynamic objects (dynamics) (dynamics of implementation methods and attributes) is all the content I share with you. I hope you can give you a reference and I hope you can support me more.