C#之Expression表达式树实例

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类型的查询对象,以及两个参数name和age。通过使用Expression方法构造Expression表达式树,然后返回一个查询结果。使用此方法进行查询:

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类型的查询对象以及一个布尔类型的参数isAscending,该参数指定排序方向。通过Expression构造表达式树,然后使用反射调用OrderBy方法进行排序,最后返回排序结果。

var sortedProductsAsc = products.OrderByPrice(true).ToList();
var sortedProductsDesc = products.OrderByPrice(false).ToList();

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#之Expression表达式树实例 - Python技术站

(0)
上一篇 2023年6月1日
下一篇 2023年6月1日

相关文章

  • 让C# Excel导入导出 支持不同版本Office

    为了让C# Excel导入导出支持不同版本Office,我们需要使用Microsoft.Office.Interop.Excel库。但是不同版本的Office对Interop.Excel库的引用稍有不同,导致在使用Interop.Excel时可能会出现错误。 因此,我们需要先根据传递给我们的Excel文件的版本来确切地确定Interop.Excel的引用版本…

    C# 2023年5月15日
    00
  • 详解ASP.NET Core Token认证

    ASP.NET Core Token认证是一种常见的身份验证机制,它使用JSON Web Token(JWT)来验证用户身份。本文将详细讲解ASP.NET Core Token认证的使用方法及项目实战。 什么是ASP.NET Core Token认证? ASP.NET Core Token认证是一种基于JWT的身份验证机制。JWT是一种开放标准,它定义了一种…

    C# 2023年5月16日
    00
  • C#如何防止程序多次运行的技巧

    C#如何防止程序多次运行的技巧有多种,下面我们将介绍两种实现方法。 方法一:利用文件锁 利用文件锁是一种简单有效的防止程序多次运行的技巧。具体实现方法如下: 首先在程序的入口处创建一个文件,例如使用FileStream类创建一个空的文件,命名为lockfile: using System.IO; // … FileStream fs = new File…

    C# 2023年5月15日
    00
  • C#语言async await工作原理示例解析

    下面是详细讲解“C#语言async await工作原理示例解析”的完整攻略,包括工作原理和示例说明。 C#语言async await工作原理示例解析 async await原理 async和await是C#5.0提供的一种异步编程方式,在处理对IO操作、CPU密集型操作等任务时都可以提供性能的提升。async关键字会告诉编译器当前的方法是一个异步方法,而aw…

    C# 2023年6月6日
    00
  • ASP.NET Core获取正确查询字符串参数示例

    标题:ASP.NET Core获取正确查询字符串参数示例 前言: 在Web应用程序中,查询字符串是一种常用的传递参数的方式。然而在ASP.NET Core中,获取查询字符串时需要特别注意一些情况,否则就可能出现获取不到参数值或者获取到错误参数值的问题。本文将详细讲解ASP.NET Core获取正确查询字符串参数的示例。 一、在Controller中获取查询字…

    C# 2023年6月3日
    00
  • 魔兽世界8.3新版本橙装幻化规则是什么 魔兽世界8.3橙装幻化规则介绍

    魔兽世界8.3新版本橙装幻化规则是什么 摘要 本篇攻略主要讲述魔兽世界8.3新版本橙装幻化规则。橙装幻化是一种帮助玩家外观扮靓,无需牺牲实用性的功能。本攻略将深入介绍橙装幻化的获取方法和具体规则。 橙装幻化获取方法 装备橙色装备:在8.3版本中,所有橙色装备都自带幻化属性。只要装备了橙色装备,玩家就可以自动获得该装备的幻化,而无需使用专门的幻化物品进行幻化。…

    C# 2023年5月31日
    00
  • C#模拟实现鼠标自动点击与消息发送功能

    C#模拟实现鼠标自动点击和消息发送是一种常见的自动化操作,可以用来提高代码的效率,下面是关于实现这一功能的攻略。 准备条件 在实现鼠标自动点击和消息发送之前,需要确保以下条件: 熟练掌握C#编程语言的基础知识; 熟悉.NET框架的基本知识和相关API; 了解鼠标点击和消息发送的基础原理。 实现步骤 鼠标自动点击 鼠标自动点击需要用到user32库,通过调用其…

    C# 2023年6月6日
    00
  • ASP.NET(C#)中操作SQLite数据库实例

    下面我将为您详细讲解ASP.NET(C#)中操作SQLite数据库的完整攻略,以及两条示例说明。 一、介绍 SQLite是轻型关系型数据库管理系统,由C语言编写而成,并支持多种编程语言。SQLite由于其小巧、快速、高效、简单易用等优点,在移动应用开发、嵌入式系统开发等领域得到了广泛应用。 ASP.NET(C#)是一种基于.NET Framework的Web…

    C# 2023年6月1日
    00
合作推广
合作推广
分享本页
返回顶部