Przemysław Kalita
Przemysław Kalita

Reputation: 2017

Passing expression into lambda

I have such class:

public class SomeClass
{
    public string Text1 { get; set; }

    public string Text2 { get; set; }

    public int Number { get; set; }
}

And I have list of this classes objects:

List<SomeClass> myList = new List<SomeClass>();

I want to query this list using LINQ (lambda syntax):

var result = myList.Where(obj => obj.Text1 == "SomeString");

Is there any way to pass property(eg. by string name), by which I want this LINQ query to be performed? In this example, I search by Text1 property, but let's say I want to invoke this search dynamically on Text1 or Text2 (determined in runtime). I want to be able to pass property name, on which this search is performed, and check whether this property is string, so that I'm sure this search CAN be performed first.

Is that possible? I know Reflections and Expressions have something to do about it, but I don't know them very well.

Thanks

Upvotes: 1

Views: 104

Answers (2)

Marc Gravell
Marc Gravell

Reputation: 1062502

You could use expression-trees?

string memberName = "Text1", value = "SomeString";
var p = Expression.Parameter(typeof(SomeClass), "obj");
var predicate = Expression.Lambda<Func<SomeClass, bool>>(
    Expression.Equal(
        Expression.PropertyOrField(p, memberName),
        Expression.Constant(value,typeof(string))
    ), p);
var result = myList.AsQueryable().Where(predicate);

or alternative for the last line:

var result = myList.Where(predicate.Compile());

Upvotes: 1

cuongle
cuongle

Reputation: 75296

The approach using Reflection:

var result = myList.Where(obj => obj.GetType()
                                    .GetProperty("Text1")
                                    .GetValue(obj)
                                    .Equals("SomeString"));

With this way you can change from "Text1" to "Text2" property.

Another approach you can use dynamic linq:

var result = myList.AsQueryable().Where("Text1=@0", "SomeString");

Dynamic LINQ is also available via nuget.

Upvotes: 1

Related Questions