使用Dynamic Linq过滤集合

Hal*_*yon 2 c# linq asp.net visual-studio

我想使用动态linq匹配对象的属性.在我的例子中,我有一个有两个属性的Turtle类.在未来,我可能会给它更多的属性.我有一个FilterTurtles()方法,它绑定到Turtle类的属性,不可扩展.我想使用动态linq使其可扩展.例如,假设我想通过Name"Gilly"和Color"Brown"进行过滤,也许还有一个名为"Breed"的未来属性.如何在FilterTurtlesWithLinq()方法中使用动态linq过滤海龟集合?

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;
    }       
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*idG 5

您不需要使用动态Linq,如何使用通用扩展方法来传递任意数量的过滤器,如下所示:

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;
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它:

var filteredTurtles = Turtles.Filter(
    t => t.Name == "Gilly", 
    t => t.Color == "Brown");
Run Code Online (Sandbox Code Playgroud)