1

I need to turn an string that represents a property name on an interface into an expression. I have most of it working, there is just 1 piece that I can't figure out at the end.

 static Expression<Func<T, int>> MakeGetter<T>(string propertyName)
    {
         var input = Expression.Parameter(typeof(T));
         var property = typeof(T).GetProperty(propertyName) ??
                                   GetProperty(propertyName, typeof(T));

         var expr = Expression.Property(input, property);
         var propType = property.PropertyType.Name;

         switch (propType.ToLower())
         {
              case "string":
                   return Expression.Lambda<Func<T, string>>(expr, input);
              case "int":
                   return Expression.Lambda<Func<T, int>>(expr, input);
         }
  }

  private static PropertyInfo GetProperty(string propertyName, Type i)
  {
       var baseInterfaces = i.GetInterfaces();
       foreach (var baseInterface in baseInterfaces)
       {
            var property = baseInterface.GetProperty(propertyName);
            return property ?? GetProperty(propertyName, baseInterface);
       }
       return null;
  }

The one problem that I have is at the end of the MakeGetter function I don't know if the function is a string or int or some other type and have no way of knowing until after I do all of the reflection, so how can I create this method, so that it is generic and will return an Expression correctly.

Microsoft DN
  • 8,858
  • 9
  • 47
  • 63
Paul Cavacas
  • 3,212
  • 2
  • 25
  • 47
  • Any reason you don't want to use `Expression.Property(input, propertyName)`? – Jon Skeet Aug 01 '13 at 13:45
  • I need to generate something that looks like Expression < Func < T, XXXXX > > – Paul Cavacas Aug 01 '13 at 14:10
  • But your method is declared to return `Expression>`... if you need it to be generic in both input *and* output, you need to have two type parameters. – Jon Skeet Aug 01 '13 at 14:15
  • I get that, but that is what I'm having a problem with. I need to generate that Expression, but I don't know what the expression out type would be until the reflection happens and I can see the property Type? – Paul Cavacas Aug 01 '13 at 14:37
  • How do you plan to use MakeGetter? I assume you don't know the property type when you call it by name? `Func`? – Ocelot20 Aug 01 '13 at 18:05
  • It is being passed into a GenericRepository object that is using it for the Sort column in a SQL statement. – Paul Cavacas Aug 01 '13 at 19:50

2 Answers2

1

Have a look here at an example of generating lambda expressions at runtime. These lines from the article show how to generate lambda expression:

var parameterExpression = Expression.Parameter(typeof(TEntity), "x");
var memberExpression = Expression.PropertyOrField(parameterExpression, prop.Name);
var memberExpressionConversion = Expression.Convert(memberExpression, typeof(object));
var lambda = Expression.Lambda<Func<TEntity, object>>(memberExpressionConversion, parameterExpression);
Martin Staufcik
  • 5,801
  • 4
  • 32
  • 46
0

Now that you've declared your intent for this in the comments, I believe that the accepted answer here is what you're looking for. Even if it's not doing exactly what you're looking for, these lines can carry over:

// TODO: Get 'type' from the property you want.
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);

You could return LambdaExpression, or just use the extension methods found in that answer, or use DynamicLinq. I guess the moral of the story (as it often is) is that its probably been done already :).

Community
  • 1
  • 1
Ocelot20
  • 9,720
  • 9
  • 49
  • 96