title: C# DynamicObject dynamic properties
body: <p>Assuming I cannot use an ExpandoObject and have to roll my own like so :-</p>
  
  <pre><code>class MyObject : DynamicObject {
      dictionary&lt;string, object&gt; _properties = dictionary&lt;string, object&gt;();
  
      public override bool TryGetMember(GetMemberBinder binder, out object result) {
          string name = binder.Name.ToLower();
  
          return _properties.TryGetValue(name, out result);
      }
  
      public override bool TrySetMember(SetMemberBinder binder, object value) {
          _properties[binder.Name.ToLower()] = value;
  
          return true;
      }
  }
  </code></pre>
  
  <p>and further down the class hierarchy I have</p>
  
  <pre><code>class MyNewObject : MyObject {
      public string Name {
          get {
              // do some funky stuff
          }
          set {
              // ditto
          }
      }
  }
  </code></pre>
  
  <p>which is quite nice as now I can do the follow :-</p>
  
  <pre><code>dynamic o = MyNewObject();
  
  o.Age = 87;     // dynamic property, handled by TrySetMember in MyObject
  o.Name = "Sam"; // non dynamic property, handled by the setter defined in MyNewObject
  </code></pre>
  
  <p>But the above assumes I know the properties (e.g. Age, Name) at compile time.</p>
  
  <p>Suppose I don't know what they will be until run time.</p>
  
  <p>How can I change the above to support properties I will only know at run time?  </p>
  
  <p>Basically I think I am asking is how I can call the code that calls TrySetMember directly so that it will either create a new property or use a getter/setter if one has been defined.</p>
  
  <p><strong>Final Solution as follows :-</strong></p>
  
  <pre><code>using System.Dynamic;
  using Microsoft.CSharp.RuntimeBinder;
  using System.Runtime.CompilerServices;
  
  class MyObject : DynamicObject {
      Dictionary&lt;string, object&gt; _properties = new Dictionary&lt;string, object&gt;();
  
      public object GetMember(string propName) {
          var binder = Binder.GetMember(CSharpBinderFlags.None,
                propName, this.GetType(),
                new List&lt;CSharpArgumentInfo&gt;{
                         CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)});
          var callsite = CallSite&lt;Func&lt;CallSite, object, object&gt;&gt;.Create(binder);
  
          return callsite.Target(callsite, this);
      }
  
      public void SetMember(string propName, object val) {
          var binder = Binder.SetMember(CSharpBinderFlags.None,
                 propName, this.GetType(),
                 new List&lt;CSharpArgumentInfo&gt;{
                         CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                         CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)});
          var callsite = CallSite&lt;Func&lt;CallSite, object, object, object&gt;&gt;.Create(binder);
  
          callsite.Target(callsite, this, val);
      }
  
      public override bool TryGetMember(GetMemberBinder binder, out object result) {
          string name = binder.Name.ToLower();
  
          return _properties.TryGetValue(name, out result);
      }
  
      public override bool TrySetMember(SetMemberBinder binder, object value) {
          _properties[binder.Name.ToLower()] = value;
  
          return true;
      }
  }
  </code></pre>