面试题答案
一键面试using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class QueryBuilder
{
public static IEnumerable<Person> FilterPersons(IEnumerable<Person> persons, string condition)
{
// 解析条件字符串为表达式树
ParameterExpression parameter = Expression.Parameter(typeof(Person), "p");
Expression body = ParseCondition(condition, parameter);
// 创建Lambda表达式
Expression<Func<Person, bool>> lambda = Expression.Lambda<Func<Person, bool>>(body, parameter);
// 使用LINQ进行筛选
return persons.AsQueryable().Where(lambda).ToList();
}
private static Expression ParseCondition(string condition, ParameterExpression parameter)
{
// 简单的解析,这里假设条件格式正确,并且只处理 && 连接符
string[] parts = condition.Split("&&");
Expression left = ParseSingleCondition(parts[0].Trim(), parameter);
for (int i = 1; i < parts.Length; i++)
{
Expression right = ParseSingleCondition(parts[i].Trim(), parameter);
left = Expression.AndAlso(left, right);
}
return left;
}
private static Expression ParseSingleCondition(string singleCondition, ParameterExpression parameter)
{
// 简单的解析,这里假设条件格式正确,并且只处理 > 和 Contains
string[] parts = singleCondition.Split(new[] { '>', ' ' }, 2);
string propertyName = parts[0].Trim();
string value = parts[1].Trim();
MemberExpression property = Expression.Property(parameter, propertyName);
if (singleCondition.Contains(">"))
{
ConstantExpression constant = Expression.Constant(int.Parse(value));
return Expression.GreaterThan(property, constant);
}
else if (singleCondition.Contains("Contains"))
{
MethodCallExpression containsCall = Expression.Call(
property,
typeof(string).GetMethod("Contains", new[] { typeof(string) }),
Expression.Constant(value.Trim('\'', '"'))
);
return containsCall;
}
throw new NotSupportedException($"Unsupported condition: {singleCondition}");
}
}
你可以这样使用:
class Program
{
static void Main()
{
List<Person> people = new List<Person>
{
new Person { Name = "John Doe", Age = 35 },
new Person { Name = "Jane Smith", Age = 28 },
new Person { Name = "John Smith", Age = 40 }
};
string condition = "Age > 30 && Name.Contains('John')";
IEnumerable<Person> result = QueryBuilder.FilterPersons(people, condition);
foreach (var person in result)
{
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
}
}
}
上述代码实现了根据用户输入的条件字符串,动态构建表达式树并进行LINQ查询筛选的功能。代码中QueryBuilder
类负责解析条件字符串并构建表达式树,FilterPersons
方法使用构建好的表达式树进行筛选。Main
方法展示了如何使用这个功能。注意,这里的解析是非常简单的,实际应用中可能需要更健壮的解析逻辑来处理各种复杂情况。