9

I'm trying to generate a "Property Selector" from a string.

Let me explain myself a bit with a Real life example:

We have a Person class with a Name (string) property.

I could manually create a "property selector" like this propertySelector writing:

Expression<Func<Person, string>> propertySelector = x => x.Name;

But I would like to get the same property selector with my method.

var propertySelector = CreatePropertySelectorExpression<Person, string>("Name");

What I have so far is this:

public static Expression<Func<TIn, TOut>> CreatePropertySelectorExpression<TIn, TOut>(string path)
{
    Expression exp = Expression.Parameter(typeof(TIn), "x");
    foreach (var property in path.Split('.'))
    {
        exp = Expression.PropertyOrField(exp, property);
    }
    return exp;
}

But... I've got and invalid cast error!

Cannot implicitly convert type 'System.Linq.Expressions.Expression' to 'System.Linq.Expressions.Expression>'. An explicit conversion exists (are you missing a cast?)

I'm very new to Expressions and I don't know how to continue :(

3
  • please could you add a real example of use? Commented Dec 27, 2014 at 18:05
  • There are some error in your code, for example Expression.Parameter will return ParameterExpression, Expression.PropertyOrField will return MemberExpression, sincerely I don't understand what would you achieve Commented Dec 27, 2014 at 18:11
  • Please, check the edit I've just made. I put a much better example. Maybe the code is wrong. I'm a newbie regarding Expressions :( Thanks in advance! Commented Dec 27, 2014 at 18:14

1 Answer 1

20

Your exp only contains the body of the lambda. But you want an actual lambda function that takes a parameter of type TIn there. So you need to create a lambda using Expression.Lambda:

var param = Expression.Parameter(typeof(TIn));
var body = Expression.PropertyOrField(param, propertyName);
return Expression.Lambda<Func<TIn, TOut>>(body, param);

Note though that the expression does not really help you much. You probably want a compiled function instead:

private static Func<TIn, TOut> CreatePropertyAccessor<TIn, TOut> (string propertyName)
{
    var param = Expression.Parameter(typeof(TIn));
    var body = Expression.PropertyOrField(param, propertyName);
    return Expression.Lambda<Func<TIn, TOut>>(body, param).Compile();
}

You can then use it like this:

var name1 = CreatePropertyAccessor<Obj, string>("Name");
var name2 = CreatePropertyAccessor<Obj, string>("Name2");
var name3 = CreatePropertyAccessor<Obj, string>("Name3");

var o = new Obj() // Obj is a type with those three properties
{
    Name = "foo",
    Name2 = "bar",
    Name3 = "baz"
};

Console.WriteLine(name1(o)); // "foo"
Console.WriteLine(name2(o)); // "bar"
Console.WriteLine(name3(o)); // "baz"
Sign up to request clarification or add additional context in comments.

1 Comment

Do you know that how to pass <Tout> dynamiclyaccording to given Type of Obj.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.