title: Get property value with Expression without knowing target type at compile time
body: <p>I'm trying to create an expression lambda to pass an object, and then get the value for named property return. However the type is only known at runtime.</p>
  
  <p>I started with the following method to handle types known at compile time:</p>
  
  <pre><code>private static Func&lt;T, object&gt; CreateExpression(string propertyName)
  {
      var arg = Expression.Parameter(typeof(T));
      var expr = Expression.Property(arg, propertyName);
      return Expression.Lambda&lt;Func&lt;T, object&gt;&gt;(expr, arg).Compile();
  }
  </code></pre>
  
  <p>Which worked perfect. However, i need to change it to handle types only known at runtime.</p>
  
  <p>I should be able to call the delegate like this:</p>
  
  <pre><code>public object GetPropertyValue(object obj)
  {
      var propertyDelegate = GetDelegate(typeof(obj));        
      var propertyValue = propertyDelegate (obj);
      return propertyValue;
  }
  
  private Func&lt;object, object&gt; GetDelegate(Type type)
  {
      // Lookup delegate in dictionary, or create if not existing
      return CreateDelegate("MyProperty", type);
  }
  </code></pre>
  
  <p>I tried changing the CreateDelegate from before, but it will not work with <code>Func&lt;object, object&gt;</code>:</p>
  
  <pre><code>Func&lt;object,object&gt; CreateDelegate(string propertyName, Type targetType)
  {
      var arg = Expression.Parameter(type);
      var body = Expression.Property(arg, name);
  
      var lambda = Expression.Lambda&lt;Func&lt;object,object&gt;&gt;(body, arg); //ArgumentException
      return lambda.Compile();
  }
  </code></pre>
  
  <p>It will not accept the Expresion.Parameter, since it is of type 'targetType', and not of type 'object'.</p>
  
  <p>Do i need a Expression.Convert or something?</p>
  
  <p>NOTE: The delegate will be called many times (Filtering method), so it need to be compiled, to ensure performance. </p>
  
  <p><strong>EDIT: Solution (provided by Marc Gravell)</strong></p>
  
  <p>the variable 'body' should be changed to the following:</p>
  
  <pre><code>var body = Expression.Convert(
               Expression.Property(
                 Expression.Convert(arg, type), 
                 name), 
               typeof(object));
  </code></pre>
  
  <p>Inner <code>Convert</code> converts input parameter to object, and the outer <code>Convert</code> converts the return value.</p>