Reputation: 14971
I want to use dynamic linq to match properties on an object. In my example, I have a Turtle class that has two properties. In the future, I may give it more properties. I have a FilterTurtles() method which is bound to the Turtle class's properties and isn't extensible. I'd like to use dynamic linq to make it extensible. For example, let's say I want to filter by the Name "Gilly" and the Color "Brown" and maybe a future property called "Breed". How can I filter the turtle collection using dynamic linq in the FilterTurtlesWithLinq() method?
public class Turtle
{
public string Name { get; set; }
public string Color { get; set; }
}
public class Filter
{
public string Name { get; set ;}
public string Value { get; set ;}
}
public class Test
{
private List<Turtle> Turtles { get; set;}
public Test()
{
Turtles = new List<Turtle>();
Turtles.Add(
{
new Turtle { Name = "Gilly", Color = "Brown" },
new Turtle { Name = "Flow", Color = "Green" },
new Turtle { Name = "Howard", Color = "Yellow" },
new Turtle { Name = "Mara", Color = "Black" },
new Turtle { Name = "Slimer", Color = "Green" },
new Turtle { Name = "Tor", Color = "Brown" },
new Turtle { Name = "Quartz", Color = "Yellow" },
new Turtle { Name = "Gilly", Color = "Green" },
new Turtle { Name = "Flow", Color = "Green" },
new Turtle { Name = "Howard", Color = "Brown" }
})
}
public IEnumerable<Turtle> FilterTurtles(string name, string color)
{
// This is the current code, but it's not extensible. If I add more properties
// to the Turtle class, then I have to add more conditional statements.
if (name != null)
{
return from t in Turtles
where t.Name == name
select t;
}
else if (color != null)
{
return from t in Turtles
where t.Color == color
select t;
}
else
{
return Turtles;
}
}
public IEnumerable<Turtle> FilterTurtlesWithLinq(List<Filter> filters)
{
// I want to use dynamic linq here. For example, I want something like this:
// "select all the turtles which match the filters"
return null;
}
}
Upvotes: 2
Views: 140
Reputation: 118937
You don't need to use dynamic Linq, how about a generic extension method that lets you pass in any number of filters, something like this:
public static IEnumerable<T> Filter<T>(this IEnumerable<T> input,
params Func<T, bool>[] filters)
{
var filtered = input;
foreach(var filter in filters)
{
filtered = filtered.Where(filter);
}
return filtered;
}
And you can use it like this:
var filteredTurtles = Turtles.Filter(
t => t.Name == "Gilly",
t => t.Color == "Brown");
Upvotes: 5