C#之Expression表达式树实例
简介
Expression表达式树是C#中一种强大的语言特性,可以通过表达式树实现动态构建Lambda表达式,让开发者可以在运行时动态的创建查询、过滤、排序等功能,大大提高了程序的灵活性。本文将详细讲解如何使用Expression表达式树实现常见的功能。
示例一:动态查询
如下是一个简单的Person类:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
现在我们需要根据Person对象的Name和Age属性进行查询,如果使用Linq语句,那么需要手动指定Name和Age的属性名:
List<Person> persons = new List<Person>
{
new Person {Name = "张三", Age = 20},
new Person {Name = "李四", Age = 30},
new Person {Name = "王五", Age = 40},
};
// 查询Name为李四的Person
var person = persons.FirstOrDefault(p => p.Name == "李四");
// 查询Age大于等于30的Person列表
var personList = persons.Where(p => p.Age >= 30).ToList();
这种做法需要手动指定属性名,代码可读性和可维护性都不高,使用Expression表达式树可以很好的解决这个问题。我们定义一个动态查询的方法,可以根据传入的属性名称和属性值进行查询:
public static class PersonExtensions
{
public static IQueryable<Person> WhereByNameAndAge(this IQueryable<Person> query, string name, int age)
{
var parameter = Expression.Parameter(typeof(Person), "p");
var propertyExpr1 = Expression.Property(parameter, nameof(Person.Name));
var propertyExpr2 = Expression.Property(parameter, nameof(Person.Age));
var constantExpr1 = Expression.Constant(name, typeof(string));
var constantExpr2 = Expression.Constant(age, typeof(int));
var conditionExpr1 = Expression.Equal(propertyExpr1, constantExpr1);
var conditionExpr2 = Expression.GreaterThanOrEqual(propertyExpr2, constantExpr2);
var andExpr = Expression.AndAlso(conditionExpr1, conditionExpr2);
var lambdaExpr = Expression.Lambda<Func<Person, bool>>(andExpr, parameter);
return query.Where(lambdaExpr);
}
}
这个方法接受一个IQueryable
var person = persons.WhereByNameAndAge("李四", 30).FirstOrDefault();
var personList = persons.WhereByNameAndAge("", 30).ToList();
示例二:动态排序
如下是一个简单的Product类:
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
}
现在需要根据Product的Price属性进行排序,但是排序的方向(升序或者降序)是不确定的,我们需要动态构建Lambda表达式。如果使用Linq语句进行排序,需要手动判断排序方向:
List<Product> products = new List<Product>
{
new Product {Name = "苹果", Price = 10},
new Product {Name = "香蕉", Price = 5},
new Product {Name = "橘子", Price = 20},
};
// 升序
var sortedProductsAsc = products.OrderBy(p => p.Price).ToList();
// 降序
var sortedProductsDesc = products.OrderByDescending(p => p.Price).ToList();
使用Expression表达式树可以强制指定排序方向,实现更加灵活的排序方法:
public static class ProductExtensions
{
public static IQueryable<Product> OrderByPrice(this IQueryable<Product> query, bool isAscending)
{
var parameterExpr = Expression.Parameter(typeof(Product), "p");
var propertyExpr = Expression.Property(parameterExpr, nameof(Product.Price));
var lambdaExpr = Expression.Lambda(propertyExpr, parameterExpr);
var methodName = isAscending ? "OrderBy" : "OrderByDescending";
var methodExpr = Expression.Call(
typeof(Queryable),
methodName,
new Type[] {query.ElementType, typeof(decimal)},
query.Expression,
lambdaExpr
);
return query.Provider.CreateQuery<Product>(methodExpr);
}
}
该方法接收IQueryable
var sortedProductsAsc = products.OrderByPrice(true).ToList();
var sortedProductsDesc = products.OrderByPrice(false).ToList();
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#之Expression表达式树实例 - Python技术站