 闽公网安备 35020302035485号
                
                闽公网安备 35020302035485号
                表达式树是一种C#中的数据结构,它以树的形式表示某些代码内部的结构。每个节点是一种称为表达式的C#对象,例如二元运算,方法调用,常量等。这种数据结构主要用于LINQ查询的内部机制和动态编程。在C#中,表达式树使在编译时表达式的结构和操作被保留下来,而不是像通常的.net代码那样被直接编译成IL。
	
这使得你可以在运行时操作这些表达式或将它们转换成其他形式。例如,你可以将一个表达式树转换为可重用的Lambda表达式,或者用于创建动态查询。或者,你可以遍历表达式树来读取和解析表达式的结构。这种技术是.NET Framework中LINQ的基础,特别是在使用LINQ to SQL和LINQ to Entities时,因为它允许在运行时将LINQ查询表达式转换为SQL查询。
public class Program
{
    public static void Main()
    {
        // 堆代码 duidaima.com
        // 参数表达式
        ParameterExpression numParam = Expression.Parameter(typeof(int), "num");
        // 常数表达式
        ConstantExpression five = Expression.Constant(5, typeof(int));
        // 比较表达式: num > 5
        BinaryExpression numGreaterThanFive = Expression.GreaterThan(numParam, five);
        // Lambda表达式
        LambdaExpression lambda1 = Expression.Lambda(numGreaterThanFive, new ParameterExpression[] { numParam });
        // 编译并执行
        Console.WriteLine("num > 5: " + ((Func<int, bool>)lambda1.Compile())(6)); // 输出: num > 5: True
    }
}
在这个示例中,我们创建了一个表达式树来表示 "num > 5" 运算。然后,我们把这个表达式树转换为一个Lambda表达式,并且编译并运行这个Lambda表达式,输出其结果。public class Person 
{
    public string Name { get; set; }
}
使用反射读取其Name属性:Person person = new Person { Name = "川建国" };
Type type = typeof(Person);
PropertyInfo propertyInfo = type.GetProperty("Name");
string name = (string)propertyInfo.GetValue(person);
Console.WriteLine(name); // 输出: 川建国
使用表达式树形式读取其Name属性:Person person = new Person { Name = "川建国" };
// 堆代码 duidaima.com
ParameterExpression objExp = Expression.Parameter(typeof(Person), "p");
MemberExpression propertyExp = Expression.Property(objExp, "Name");
LambdaExpression lambdaExp = Expression.Lambda(propertyExp, objExp);
//编译表达式
Func<Person, string> getPersonName = (Func<Person, string>)lambdaExp.Compile();
string name = getPersonName(person);
Console.WriteLine(name); // 输出: 川建国
我们可以看到,虽然表达式树的代码看起来更复杂一些,但实际上它运行得更快,特别是在需要重复执行的情况下,因为编译过的委托可以重复使用,而反射每次都需要重新解析类型信息和方法信息。