Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linq expression as parameter

Tags:

c#

linq

I have to query collection like this:

myList.Where(s => myFilters.Contains(s.CountryCode))

s.CountryCode above is an example. I want to make it variable and call for different columns, like this:

myList.Where(s => myFilters.Contains(s.City))
myList.Where(s => myFilters.Contains(s.Region))
myList.Where(s => myFilters.Contains(s.Zipcode))

So I would like to define function where the column expression is a parameter. What is the signature of such function?

public void MySelect( ??? )
{
    myList.Where(s => myFilters.Contains(???);
}

myList is an ObservableCollection, and myFilters is List<string>

like image 897
iljon Avatar asked Feb 11 '16 11:02

iljon


2 Answers

Put this extension method in a static class:

public static IEnumerable<T> WhereContains<T, TValue> (this IEnumerable<T> obj, IEnumerable<TValue> container, Func<T, TValue> propertyAccess)
{
    return obj.Where(o => container.Contains(propertyAccess(o)));
}

The way this extension method works is that it accepts a lambda function that resolves the property given an object of your type. So you just need to pass a simple lamba like x => x.City to it.

Since it’s completely generic and not specific to your one myFilters collection, you also need to pass it to the function. But that allows you to use this WhereContains for many other situations too.

Using it looks like this:

// Test is a class with two string properties `City` and `Region`
var myList = new List<Test>{
    new Test() { City = "asdf", Region = "fdsa" },
    new Test() { City = "foo", Region = "bar" },
    new Test() { City = "bar", Region = "baz" }
};

var myFilters = new List<string> { "asdf", "bar" };

myList.WhereContains(myFilters, x => x.City); // contains asdf/fdsa and bar/baz
myList.WhereContains(myFilters, x => x.Region); // contains foo/bar
like image 82
poke Avatar answered Oct 07 '22 12:10

poke


You can use Reflection

 public void MySelect(string column)
 {
   var result  = myList.Where(s => myFilters.Contains(s.GetType().GetProperty(column)));
 }
like image 27
Viru Avatar answered Oct 07 '22 12:10

Viru