当前位置: 首页 > news >正文

C# 表达式树详解

总目录


前言

在 C# 中,表达式树(Expression Trees)是一种强大的特性,允许开发者将代码表示为数据结构。这使得我们可以在运行时动态地创建和操作代码逻辑,广泛应用于 LINQ 查询、动态方法生成以及反射等领域。本文将深入探讨 C# 表达式树的创建、操作和应用场景。


一、什么是表达式树?

1. 定义

表达式树是一种树状数据结构,将代码表示为一棵树,其中每个节点代表一个操作或数据(如属性访问、方法调用、运算等)。例如,表达式 x + y 可拆解为三个节点:参数 x、参数 y 和加法运算符。

在 C# 中,表达式树由 System.Linq.Expressions 命名空间中的类来表示。表达式树在C#中广泛应用于动态LINQ查询、动态编译等领域。

表达式树是一种数据结构,用于表示代码的逻辑结构(代码中的逻辑和运算)。与普通的委托不同,表达式树不是直接执行代码,而是将其转换为一个可查询和操作的对象模型。这使得我们可以动态地构建、分析和修改代码逻辑。

2. 表达式树的基本组件

  • Expression:表示表达式树的根节点或子表达式。
    • ParameterExpression:表示方法的参数。
    • MemberExpression:表示对对象成员(如属性或字段)的访问。
    • MethodCallExpression:表示对方法的调用。
    • BinaryExpression:表示二元运算(如加法、比较等)。
    • UnaryExpression:表示一元运算(如取反、递增等)。
    • ConstantExpression:表示常量值。
    • LambdaExpression:表示Lambda表达式主体。

2. 与委托和 Lambda 的区别

特性表达式树委托
表现形式可分析的树结构编译后的IL指令
运行时行为可动态修改和重组固定不可变
主要用途代码生成、动态查询直接方法调用
执行方式需编译为委托后执行直接调用

委托:编译时确定的函数指针,直接执行代码。
Lambda 表达式:可隐式转换为委托或表达式树。
表达式树:将代码逻辑存储为数据结构,支持运行时动态解析和修改。

3. 核心特性

不可变性:创建后无法修改,每次操作生成新树。
可编译性:通过 Compile() 方法生成委托执行。
高效性:相比反射,编译后的表达式树性能接近原生代码。

4. 表达式树的组成部分

一个典型的表达式树包含以下几个部分:

  • 参数:使用 ParameterExpression 定义lambda表达式的参数。
  • 主体:表达式树的主体可以是单一的表达式或多个表达式的组合,例如二元表达式 BinaryExpression 用于表示加法、乘法等操作。
  • lambda表达式:将参数和主体组合成一个lambda表达式,使用 Expression.Lambda 方法创建。

二、表达式树构建方式

1. 通过Lambda自动转换

Expression<Func<int, bool>> expr = num => num > 10 && num < 20;
public class Program
{
    public static void Main()
    {
        Expression<Func<int, bool>> expr = num => num > 10 && num < 20;
        Console.WriteLine(expr.ToString()); //输出:num => ((num > 10) AndAlso (num < 20))

        //编译并执行表达式树
        Func<int, bool> func = expr.Compile();        
        Console.WriteLine(func.Invoke(18)); //输出:True
    }
}

2. 手动构建表达式树

1)创建简单的表达式树

示例 1

表达式树通常使用 System.Linq.Expressions 命名空间中的类来构建。以下是一个简单的例子,展示如何创建一个基本的表达式树:

using System;
using System.Linq.Expressions;

public class Program
{
    public static void Main()
    {
        // 创建参数表达式 x
        ParameterExpression param = Expression.Parameter(typeof(int), "x");

        // 创建常量表达式 5
        ConstantExpression five = Expression.Constant(5, typeof(int));

        // 创建二元表达式 x + 5
        BinaryExpression add = Expression.Add(param, five);

        // 创建表达式树 x => (x + 5)
        Expression<Func<int, int>> expressionTree = Expression.Lambda<Func<int, int>>(add, param);
        Console.WriteLine(expressionTree);  // 输出: x => (x + 5)

        // 编译并执行表达式树
        Func<int, int> compiledFunc = expressionTree.Compile();
        Console.WriteLine(compiledFunc(10)); // 输出: 15
    }
}
示例 2

以下示例展示了如何创建一个简单的表达式树,该树表示两个数相加的表达式:

public class Program
{
    public static void Main()
    {
        // 创建参数表达式
        ParameterExpression a = Expression.Parameter(typeof(int), "a");
        ParameterExpression b = Expression.Parameter(typeof(int), "b");

        // 创建加法表达式
        BinaryExpression add = Expression.Add(a, b);

        // 创建 lambda 表达式
        Expression<Func<int, int, int>> lambda = Expression.Lambda<Func<int, int, int>>(add, a, b);
        Console.WriteLine(lambda);  // 输出:(a, b) => (a + b)

        // 编译并调用表达式树
        Func<int, int, int> func = lambda.Compile();
        int result = func(2, 3);
        Console.WriteLine($"Result: {result}"); // 输出: Result: 5
    }
}

2)构建复杂的表达式树

除了简单的算术运算,我们还可以构建更复杂的表达式树,例如条件判断、方法调用等。

示例1:基本组合
using System;
using System.Linq.Expressions;
public class Program
{
    public static void Main()
    {
        // 定义参数
        ParameterExpression x = Expression.Parameter(typeof(int), "x");
        // 创建表达式:x * 2
        BinaryExpression multiply = Expression.Multiply(x, Expression.Constant(2));
        // 创建表达式:x * 2 + 3
        BinaryExpression add = Expression.Add(multiply, Expression.Constant(3));
        // 创建lambda表达式
        Expression<Func<int, int>> lambda = Expression.Lambda<Func<int, int>>(add, x);
        // 输出lambda表达式
        Console.WriteLine(lambda); // 输出: x => (x * 2 + 3)
        // 编译lambda表达式
        Func<int, int> compiledLambda = lambda.Compile();
        // 执行编译后的lambda表达式
        int result = compiledLambda(5);
        Console.WriteLine($"Result of compiled lambda: {result}"); // 输出: 13
    }
}
示例2: 条件判断

下面的例子展示了如何构建一个包含条件判断的表达式树:

using System;
using System.Linq.Expressions;

public class Program
{
    public static void Main()
    {
        // 创建参数表达式 x
        ParameterExpression param = Expression.Parameter(typeof(int), "x");

        // 创建常量表达式 10
        ConstantExpression ten = Expression.Constant(10, typeof(int));

        // 创建条件表达式 x > 10
        BinaryExpression greaterThan = Expression.GreaterThan(param, ten);

        // 创建 if-true 表达式 x * 2
        BinaryExpression trueResult = Expression.Multiply(param, Expression.Constant(2, typeof(int)));

        // 创建 if-false 表达式 x - 1
        BinaryExpression falseResult = Expression.Subtract(param, Expression.Constant(1, typeof(int)));

        // 创建条件表达式
        ConditionalExpression conditional = Expression.Condition(greaterThan, trueResult, falseResult);

        // 创建表达式树 x=>(x > 10)? (x * 2):(x - 1)
        Expression<Func<int, int>> expressionTree = Expression.Lambda<Func<int, int>>(conditional, param);
        Console.WriteLine(expressionTree);  // 输出:x => IIF((x > 10), (x * 2), (x - 1))

        // 编译并执行表达式树
        Func<int, int> compiledFunc = expressionTree.Compile();
        Console.WriteLine(compiledFunc(15)); // 输出: 30
        Console.WriteLine(compiledFunc(5));  // 输出: 4
    }
}
示例3:方法调用

表达式树还可以用于表示方法调用。以下是一个调用静态方法的例子:

using System;
using System.Linq.Expressions;

public class Program
{
    public static int Add(int a, int b)
    {
        return a + b;
    }

    public static void Main()
    {
        // 创建参数表达式 x 和 y
        ParameterExpression paramX = Expression.Parameter(typeof(int), "x");
        ParameterExpression paramY = Expression.Parameter(typeof(int), "y");

        // 获取 Add 方法的信息
        MethodInfo addMethod = typeof(Program).GetMethod("Add", new[] { typeof(int), typeof(int) });

        // 创建方法调用表达式
        MethodCallExpression call = Expression.Call(addMethod, paramX, paramY);

        // 创建表达式树
        Expression<Func<int, int, int>> expressionTree = Expression.Lambda<Func<int, int, int>>(call, paramX, paramY);

        // 编译并执行表达式树
        Func<int, int, int> compiledFunc = expressionTree.Compile();
        Console.WriteLine(compiledFunc(3, 7)); // 输出: 10
    }
}
示例4:复杂表达式树的动态拼接

表达式树支持动态逻辑,例如根据条件生成查询:

using System;
using System.Linq.Expressions;
public class Person
{
    public int Age { get; set; }
    public string Name { get; set; }
}
public class Program
{
    public static void Main()
    {
        // 动态生成 "p.Age > 18 && p.Name == "Alice""
        // 创建参数表达式 p
        var param = Expression.Parameter(typeof(Person), "p");

        // 创建条件表达式 p.Age > 18
        var ageCheck = Expression.GreaterThan(Expression.Property(param, "Age"), Expression.Constant(18));

        // 创建条件表达式 p.Name == "Alice"
        var nameCheck = Expression.Equal(Expression.Property(param, "Name"), Expression.Constant("Alice"));

        // 创建条件表达式 p.Age > 18 && p.Name == "Alice"
        var combined = Expression.AndAlso(ageCheck, nameCheck);

        // 创建Lambda表达式 p=>p.Age > 18 && p.Name == "Alice"
        var lambda = Expression.Lambda<Func<Person, bool>>(combined, param);
        Console.WriteLine(lambda);  // 输出:p => ((p.Age > 18) AndAlso (p.Name == "Alice"))

        // 编译并执行表达式树
        Func<Person, bool> compiledFunc = lambda.Compile();
        Console.WriteLine(compiledFunc(new Person { Age = 16, Name = "Jack" }));  // 输出: False
        Console.WriteLine(compiledFunc(new Person { Age = 19, Name = "Alice" })); // 输出: True
    }
}

此特性在 ORM 框架(如 Entity Framework)中用于动态生成 SQL。

三、应用场景

1. 应用场景

  • 动态查询:用于构建动态LINQ查询,特别适用于ORM框架。
  • 动态代码生成与编译:在运行时生成并编译代码,适用于需要动态生成逻辑的应用场景。
  • 元编程:通过解析和修改表达式树,实现高级编程模式,如方法拦截。
  • 动态条件判断:根据外部输入或配置动态调整业务逻辑。
  • 自定义运算符重载:扩展现有类型的运算符行为。

2. 应用场景示例

示例1:简单动态查询

表达式树最常见的一种应用是在动态查询中。例如,在LINQ to SQL中,表达式树被用来将C#查询转换为SQL查询。

using System;
using System.Linq;
using System.Linq.Expressions;

public class Program
{
    public static void Main()
    {
        // 创建一个简单的列表
        var numbers = new[] { 1, 2, 3, 4, 5 };

        // 创建表达式树 x => x > 3
        ParameterExpression param = Expression.Parameter(typeof(int), "x");
        ConstantExpression three = Expression.Constant(3, typeof(int));
        BinaryExpression greaterThan = Expression.GreaterThan(param, three);
        Expression<Func<int, bool>> expressionTree = Expression.Lambda<Func<int, bool>>(greaterThan, param);

        // 使用表达式树进行查询
        var query = numbers.Where(expressionTree.Compile());
        Console.WriteLine(string.Join(",",query)); // 输出:4,5
    }
}

示例2:动态构建复杂查询条件

在 LINQ 查询中,表达式树可以用于动态构建查询条件,使得查询更加灵活。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

public class Program
{
    public static void Main()
    {
        List<Product> products = new List<Product>
        {
            new Product { Id = 1, Name = "Laptop", Price = 999.99m },
            new Product { Id = 2, Name = "Mouse", Price = 19.99m },
            new Product { Id = 3, Name = "Keyboard", Price = 49.99m }
        };

        // 动态构建查询条件 p.Price >= 50.00
        ParameterExpression parameter = Expression.Parameter(typeof(Product), "p");
        MemberExpression priceMember = Expression.Property(parameter, "Price");
        ConstantExpression minPrice = Expression.Constant(50.00m);
        BinaryExpression condition = Expression.GreaterThanOrEqual(priceMember, minPrice);

        // 构建 lambda 表达式 p => p.Price >= 50.00
        Expression<Func<Product, bool>> predicate = Expression.Lambda<Func<Product, bool>>(condition, parameter);

        // 使用表达式树进行查询
        var expensiveProducts = products.Where(predicate.Compile());
        Console.WriteLine("Products with price >= 50.00:");
        foreach (var product in expensiveProducts)
        {
            Console.WriteLine($"{product.Name}: {product.Price}");
        }
    }
}

运行结果:

Products with price >= 50.00:
Laptop: 999.99

示例3:动态生成代码

表达式树还可以用于在运行时生成并编译新的代码。这对于需要根据用户输入或配置动态生成逻辑的应用程序非常有用。

using System;
using System.Linq.Expressions;

public class Program
{
    public static void Main()
    {
        // 动态生成一个 lambda 表达式 x => x * 2
        ParameterExpression param = Expression.Parameter(typeof(int), "x");
        BinaryExpression multiply = Expression.Multiply(param, Expression.Constant(2, typeof(int)));
        Expression<Func<int, int>> expressionTree = Expression.Lambda<Func<int, int>>(multiply, param);

        // 编译并执行表达式树
        Func<int, int> compiledFunc = expressionTree.Compile();
        Console.WriteLine(compiledFunc(5)); // 输出: 10
    }
}

示例4:元编程

表达式树可以用于元编程,即编写能够生成或修改其他代码的代码。例如,可以通过解析表达式树来实现AOP(面向切面编程)中的方法拦截功能。

假设我们有一个简单的日志拦截器,可以在方法调用前后记录日志。

using System;
using System.Linq.Expressions;
using System.Reflection;

public class Program
{
    public static void Main()
    {
        // 创建表达式树来调用 Add 方法
        ParameterExpression paramX = Expression.Parameter(typeof(int), "x");
        ParameterExpression paramY = Expression.Parameter(typeof(int), "y");

        MethodInfo addMethod = typeof(Program).GetMethod("Add", BindingFlags.Public | BindingFlags.Static);
        MethodCallExpression call = Expression.Call(addMethod, paramX, paramY);

        // 创建带日志的表达式树
        Expression<Action<int, int>> logExpression = CreateLoggedExpression<int, int>(call, paramX, paramY);

        // 编译并执行表达式树
        Action<int, int> loggedAction = logExpression.Compile();
        loggedAction(3, 7);
    }

    public static int Add(int a, int b)
    {
        Console.WriteLine($"Add:{a} + {b} ={a + b}");
        return a + b;
    }

    private static Expression<Action<T1, T2>> CreateLoggedExpression<T1, T2>(MethodCallExpression methodCall, ParameterExpression param1, ParameterExpression param2)
    {
        //创建 代码块
        var block = Expression.Block(
            Expression.Call(null, typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expression.Constant("Entering Add")),
            methodCall,
            Expression.Call(null, typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expression.Constant("Exiting Add"))
        );
        
        //以上功能类似于
        //Console.WriteLine("Entering Add");
        //Add(10,10);
        //Console.WriteLine("Exiting Add");

        return Expression.Lambda<Action<T1, T2>>(block, param1, param2);
    }
}

运行结果:

Entering Add
Add:3 + 7 =10
Exiting Add

示例5:动态条件判断

表达式树可以用于动态构建条件判断逻辑,适用于需要根据外部输入或配置动态调整业务逻辑的场景。

using System;
using System.Linq.Expressions;

public class Program
{
    public static void Main()
    {
        // 创建参数表达式 x
        ParameterExpression param = Expression.Parameter(typeof(int), "x");

        // 创建常量表达式 10
        ConstantExpression ten = Expression.Constant(10, typeof(int));

        // 创建条件表达式 x > 10
        BinaryExpression greaterThan = Expression.GreaterThan(param, ten);

        // 创建 if-true 表达式 x * 2
        BinaryExpression trueResult = Expression.Multiply(param, Expression.Constant(2, typeof(int)));

        // 创建 if-false 表达式 x - 1
        BinaryExpression falseResult = Expression.Subtract(param, Expression.Constant(1, typeof(int)));

        // 创建条件表达式
        ConditionalExpression conditional = Expression.Condition(greaterThan, trueResult, falseResult);

        // 创建表达式树
        Expression<Func<int, int>> expressionTree = Expression.Lambda<Func<int, int>>(conditional, param);

        // 编译并执行表达式树
        Func<int, int> compiledFunc = expressionTree.Compile();
        Console.WriteLine(compiledFunc(15)); // 输出: 30
        Console.WriteLine(compiledFunc(5));  // 输出: 4
    }
}

示例6:自定义运算符重载

表达式树可以用于实现自定义运算符重载,适用于需要扩展现有类型的行为的场景。

假设我们有一个自定义类型 Vector,并希望为其添加加法运算符。

using System;
using System.Linq.Expressions;

public struct Vector
{
    public double X { get; set; }
    public double Y { get; set; }

    public Vector(double x, double y)
    {
        X = x;
        Y = y;
    }

    public static Vector operator +(Vector v1, Vector v2)
    {
        return new Vector(v1.X + v2.X, v1.Y + v2.Y);
    }
}

public class Program
{
    public static void Main()
    {
        // 创建两个 Vector 实例
        Vector v1 = new Vector(1, 2);
        Vector v2 = new Vector(3, 4);

        // 创建表达式树来表示 v1 + v2
        ParameterExpression paramV1 = Expression.Parameter(typeof(Vector), "v1");
        ParameterExpression paramV2 = Expression.Parameter(typeof(Vector), "v2");

        BinaryExpression add = Expression.Add(paramV1, paramV2);

        // 创建表达式树
        Expression<Func<Vector, Vector, Vector>> expressionTree = Expression.Lambda<Func<Vector, Vector, Vector>>(add, paramV1, paramV2);

        // 编译并执行表达式树
        Func<Vector, Vector, Vector> compiledFunc = expressionTree.Compile();
        Vector result = compiledFunc(v1, v2);
        Console.WriteLine($"({result.X}, {result.Y})"); // 输出: (4, 6)
    }
}

3. 高级实战场景

场景1:动态查询构造

using System;
using System.Linq.Expressions;

public class Person
{
    public int Age { get; set; }
    public string Name { get; set; }
}

public class Program
{
    public static IQueryable<Person> BuildDynamicQuery(IQueryable<Person> source, string propertyName, object value)
    {
        var param = Expression.Parameter(typeof(Person), "p");
        var property = Expression.Property(param, propertyName);
        var constant = Expression.Constant(value);
        var body = Expression.Equal(property, constant);
        var lambda = Expression.Lambda<Func<Person, bool>>(body, param);

        return source.Where(lambda);
    }
    public static void Main()
    {
        List<Person> people = new List<Person>
        {
            new Person { Name = "Alice", Age = 30 },
            new Person { Name = "Bob", Age = 25 },
            new Person { Name = "Charlie", Age = 35 },
            new Person { Name = "David", Age = 25 }
        };
        // 通过 BuildDynamicQuery 方法 可以动态筛选 特定属性等于特定值的数据
        var query = BuildDynamicQuery(people.AsQueryable(), "Age", 25);
        Console.WriteLine(string.Join(",",query.Select(x=>x.Name)));
        // 输出:Bob,David
    }
}

如果是在ORM中,则会通过如下形式调用:

// 使用示例
var query = BuildDynamicQuery(dbContext.Persons, "Age", 25);

场景2:高性能对象映射

using System;
using System.Collections.Concurrent;
using System.Linq.Expressions;
using System.Reflection;

public static class Mapper<TSource, TTarget>
{
    private static readonly ConcurrentDictionary<(Type, Type), Func<TSource, TTarget>> _cache = new ConcurrentDictionary<(Type, Type), Func<TSource, TTarget>>();

    public static Func<TSource, TTarget> CreateMapper()
    {
        var cacheKey = (typeof(TSource), typeof(TTarget));
        return _cache.GetOrAdd(cacheKey, key =>
        {
            var sourceParam = Expression.Parameter(typeof(TSource), "source");
            var bindings = new List<MemberBinding>();

            foreach (var targetProp in typeof(TTarget).GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                var sourceProp = typeof(TSource).GetProperty(targetProp.Name, BindingFlags.Public | BindingFlags.Instance);
                if (sourceProp == null || !sourceProp.CanRead || !targetProp.CanWrite)
                    continue;

                // 检查属性类型是否匹配
                if (sourceProp.PropertyType != targetProp.PropertyType)
                    continue;

                var propAccess = Expression.Property(sourceParam, sourceProp);
                bindings.Add(Expression.Bind(targetProp, propAccess));
            }

            var body = Expression.MemberInit(
                Expression.New(typeof(TTarget)),
                bindings
            );

            var lambda = Expression.Lambda<Func<TSource, TTarget>>(body, sourceParam);
            return lambda.Compile();
        });
    }
}

// 示例类定义
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
}

public class PersonDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var person = new Person
        {
            Id = 1,
            Name = "John Doe",
            BirthDate = new DateTime(1990, 1, 1)
        };

        var mapper = Mapper<Person, PersonDto>.CreateMapper();
        var dto = mapper(person);

        Console.WriteLine($"Id: {dto.Id}, Name: {dto.Name}, BirthDate: {dto.BirthDate}");
    }
}

四、高级技巧与优化

1. 表达式树缓存策略

private static ConcurrentDictionary<string, Delegate> _cache 
    = new ConcurrentDictionary<string, Delegate>();

public Func<TInput, TResult> GetOrCreateCompiler<TInput, TResult>(
    Expression<Func<TInput, TResult>> expr)
{
    string key = expr.ToString();
    return (Func<TInput, TResult>)_cache.GetOrAdd(key, _ => {
        return expr.Compile();
    });
}

2. 动态修改表达式树

public class Program
{
    public static void Main(string[] args)
    {
        Expression<Func<int, int>> original = x => x * 2;
        var modifier = new ExpressionModifier();
        var modifiedExpr = (Expression<Func<int, int>>)modifier.Visit(original);
        Console.WriteLine(modifiedExpr);    //输出:x => (x + 2)

        var func = modifiedExpr.Compile();
        Console.WriteLine(func(1)); // 输出:3
    }
}

class ExpressionModifier : ExpressionVisitor
{
    protected override Expression VisitBinary(BinaryExpression node)
    {
        if (node.NodeType == ExpressionType.Multiply)
        {
            return Expression.Add(node.Left, node.Right);
        }
        return base.VisitBinary(node);
    }
}

五、性能关键点

1. 编译性能对比

操作耗时(μs)
直接调用0.01
委托调用0.03
首次编译表达式树100-500
缓存后表达式树调用0.05

2. 优化建议

  • 预编译高频表达式:启动时编译常用表达式
  • 避免重复编译:使用字典缓存编译结果,避免重复编译高频使用的表达式树。
  • 减少闭包捕获:优先使用静态方法
  • 使用Expression.Compile(preferInterpretation: true):.NET Core 3.0+支持解释模式
  • 避免过度动态化:静态代码在可预测场景下更高效。

六、使用须知

1. 注意事项

1)不可变性

修改需重新生成树结构

2)平台限制

  • 平台兼容性:确保目标环境支持 System.Linq.Expressions
  • AOT编译环境(如iOS):部分动态编译功能受限
  • 部分表达式节点:在Entity Framework等Provider中不支持

3)安全风险

// 危险:允许用户输入表达式
var expr = "x => x.Name.Contains(\"" + userInput + "\")";
// 可能引发注入攻击,应使用白名单验证

4)调试复杂性

动态生成的树结构难以直接调试,需借助可视化工具。

2. 表达式树的优缺点

1)优点

  • 动态性:允许在运行时动态生成和修改代码逻辑。
  • 灵活性:适用于延迟执行和针对不同数据源的优化查询。
  • 可分析性:表达式树可以被分析和转换,便于实现复杂的逻辑。
  • 性能优化:通过编译表达式树生成的代码,可以获得接近直接编译代码的性能。
  • 代码复用:表达式树可以复用现有的逻辑,减少重复代码的编写。

2)缺点

  • 性能开销:表达式树的构建和编译需要额外的性能开销。
  • 复杂性:表达式树的代码相对复杂,学习曲线较陡。

结语

回到目录页:C#/.NET 知识汇总
希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。


参考资料:
MSDN文档 表达式树
DLR (Dynamic Language Runtime)
c#:表达式树概念及应用场景(Expression)
c#:深入理解表达式树

相关文章:

  • SpringBoot的并行SQL任务并完成所有任务之后返回操作
  • Shell条件判断
  • PortSwigger——OAuth 2.0 authentication vulnerabilities
  • JavaScript代码性能优化
  • NPU、边缘计算与算力都是什么啊?
  • 应用层之网络应用模型,HTTP/HTTPS协议
  • ChatGPT、DeepSeek、Grok:AI 语言模型的差异与应用场景分析
  • 图神经网络学习笔记—纯 PyTorch 中的多 GPU 训练(专题十二)
  • (七)Spring Boot学习——Redis使用
  • 安卓编译问题
  • 人工智能之数学基础:如何将线性变换转换为矩阵?
  • BUG 详解 [软件测试]
  • Celery在Django中的作用
  • 【Python+HTTP接口】POST请求不同请求头构造
  • Certbot实现SSL免费证书自动续签(CentOS 7版 + Docker部署的nginx)
  • 【MySQL篇】基本查询实战OJ
  • [Hello-CTF]RCE-Labs超详细WP-Level13Level14(PHP下的0/1构造RCE命令简单的字数限制RCE)
  • python爬虫Scrapy(5)之CrawlSpider
  • vscode--工作区和相对路径
  • Nginx静态资源访问设置
  • “一百零一个愿望——汉字艺术展”亮相意大利威尼斯
  • 新能源汽车,告别混乱创新
  • 内塔尼亚胡:以军将在未来几天“全力进入”加沙
  • 第二期人工智能能力建设研讨班在京开班,近40国和区域组织代表参加
  • 刘国中:持续加强护士队伍建设,更好保障人民身体健康
  • 全球前瞻|特朗普访问中东三国,印巴军方将于12日再次对话