title: How to access a dynamic object's property dynamically (by variable)?
body: <p>I have a class named <code>Configuration</code>which inherits from <code>DynamicObject</code>. It it a <code>Dictionary&lt;string, object&gt;</code>. In the constructor, it reads a text file and loads all the values from it splitted by <code>=</code>, so you can create dynamic configuration objects like this:</p>
  
  <pre><code>dynamic configuration = new Configuration("some_file.ini");
  </code></pre>
  
  <p>Here is my full class:</p>
  
  <pre><code>public sealed class Configuration : DynamicObject
  {
      private string Path { get; set; }
      private Dictionary&lt;string, object&gt; Dictionary { get; set; }
  
      public Configuration(string fileName)
      {
          this.Path = fileName;
          this.Dictionary = new Dictionary&lt;string, object&gt;();
  
          this.Populate();
      }
  
      ~Configuration()
      {
          if (this.Dictionary != null)
          {
              this.Dictionary.Clear();
          }
      }
  
      private void Populate()
      {
          using (StreamReader reader = new StreamReader(this.Path))
          {
              string line;
              string currentSection = string.Empty;
  
              while ((line = reader.ReadLine()) != null)
              {
                  if (string.IsNullOrWhiteSpace(line))
                  {
                      continue;
                  }
  
                  if (line.StartsWith("[") &amp;&amp; line.EndsWith("]"))
                  {
                      currentSection = line.Trim('[', ']');
                  }
                  else if (line.Contains("="))
                  {
                      this.Dictionary.Add(string.Format("{0}{1}{2}",
                          currentSection,
                          (currentSection != string.Empty) ? "_" : string.Empty,
                          line.Split('=')[0].Trim()),
                          ParseValue(line.Split('=')[1].Trim().Split(';')[0]));
                  }
              }
          }
      }
  
      private object ParseValue(string value)
      {
          if (string.IsNullOrWhiteSpace(value))
              return string.Empty;
  
          if (value.StartsWith("\"") &amp;&amp; value.EndsWith("\""))
              return value.Substring(1, value.Length - 1);
  
          if (IsNumeric(value))
              return Convert.ToInt32(value);
  
          // TODO: FIXME Floating values (not to be confuse with IPAddress).
          //if (IsFloating(value))
          //    return Convert.ToDouble(value);
  
          if (string.Compare(value, "true", StringComparison.OrdinalIgnoreCase) == 0)
              return true;
  
          if (string.Compare(value, "false", StringComparison.OrdinalIgnoreCase) == 0)
              return false;
  
          return value;
      }
  
      public override bool TryGetMember(GetMemberBinder binder, out object result)
      {
          if (this.Dictionary.ContainsKey(binder.Name))
          {
              if (this.Dictionary[binder.Name] == null)
              {
                  result = null;
              }
              else
              {
                  result = this.Dictionary[binder.Name];
              }
  
              return true;
          }
  
          throw new ConfigurationException(binder.Name);
      }
  
      public override string ToString()
      {
          string result = this.Path + " [ ";
  
          int processed = 0;
  
          foreach (KeyValuePair&lt;string, object&gt; value in this.Dictionary)
          {
              result += value.Key;
              processed++;
  
              if (processed &lt; this.Dictionary.Count)
              {
                  result += ", ";
              }
          }
  
          result += " ]";
  
          return result;
      }
  
      private static bool IsNumeric(string value)
      {
          foreach (char c in value)
              if (!char.IsDigit(c))
                  return false;
  
          return true;
      }
      private static bool IsFloating(string value)
      {
          foreach (char c in value)
              if (!char.IsDigit(c) &amp;&amp; c != '.')
                  return false;
  
          return true;
      }
  
      private class NullObject { }
  }
  </code></pre>
  
  <p>Everything is working flawlessly. I've overriden <code>TryGetMember</code> and I'm returning the object based on the <code>GetMemberBinder</code> <code>Name</code> property. However, I'm facing a problem.</p>
  
  <p>When I execute the following code:</p>
  
  <pre><code>string s = "some_config_key";
  
  string d = configuration.s;
  </code></pre>
  
  <p>It retrieves the value of the key <code>s</code> rather than <code>some_config_key</code>, meaning that it doesn't evalute the value of the variable <code>s</code>. Is there a workaround for this?</p>
  
  <p>Thanks.</p>