agnieszka
agnieszka

Reputation: 15345

How to create lambda expression that returns object's property, having this property's name?

I am completely lost on this one. I have a piece of code that does what I need when implemented like this:

return filters.Add(m => m.Metadata.RecordId).IsEqualTo(1);

where m is a TestObj class object and Add method's argument is Expression<Func<TestObj,bool?>>.

Now the problem is that I cannot hardcode m.Metadata.RecordId inside Add, because what I get here is a string that informs me about the property that should be used, in this case "Metadata.RecordId". what I need to do is to construct such an expression with this string that will do the same thing as m => m.Metadata.RecordId does. I need something like this:

string propertyName = "Metadata.RecordId";
Expression expr = null;//create expression here somehow that will do the same as m => m.Metadata.RecordId
return filters.Add(expr).IsEqualTo(1); 

How do I do that?

Upvotes: 3

Views: 4493

Answers (2)

NSGaga
NSGaga

Reputation: 14302

I'm not sure what exactly you want there as an output (bool, int and comparing),
But this should get you on the right track...

public static void Test(string propertyPath)
{
    var props = propertyPath.Split('.');
    Expression parameter = Expression.Parameter(typeof(TestObj), "x");
    Expression property = parameter;
    foreach (var propertyName in props)
        property = Expression.Property(property, propertyName);
    Expression<Func<TestObj, int>> lambdaExpression =
        Expression.Lambda<Func<TestObj, int>>(property, parameter as ParameterExpression);
    Add(lambdaExpression);
}
static void Add(Expression<Func<TestObj, int>> paramExp)
{
    TestObj obj = new TestObj { Metadata = new Metadata { RecordId = 1, Name = "test" } };
    var id = paramExp.Compile()(obj);
}

And you can also check this post of Jon's which nicely describes how that works...
Use reflection to get lambda expression from property Name

Upvotes: 1

Oliver
Oliver

Reputation: 45071

What about this call:

return filters.Add(m => ReflectionMagic(m, "Metadata.RecordId").IsEqualTo(1);

The method would have this signature:

public object ReflectionMagic(object source, string property);

If that would work, you could do something like this:

var propertyTree = property.Split('.');

foreach(var propertyName in propertyTree)
{
     var propInfo = source.GetType().GetProperty(propertyName);
     var source = propInfo.GetValue(source, null);
}

return source;

Be aware that any kind of argument and return value checks are missing and are left as an excercise to the reader.

Upvotes: 0

Related Questions