C# 表达式树 Expression.Dynamic 用于创建动态操作,这些操作在编译时无法确定,而是在运行时根据对象的实际类型进行解析。这在处理动态类型或 COM 对象等场景中非常有用。
以下是一个 Expression.Dynamic 的用法示例,它演示了如何使用动态表达式树调用对象的成员:
using System;
using System.Dynamic;
using System.Linq.Expressions;
public class Example
{
public static void Main(string[] args)
{
// 创建一个动态对象
dynamic obj = new ExpandoObject();
obj.Name = "John Doe";
obj.Age = 30;
// 创建一个动态表达式树,用于调用对象的 Name 属性
ParameterExpression parameter = Expression.Parameter(typeof(object), "obj");
Expression dynamicExpression = Expression.Dynamic(
(Binder.GetMember(0, "Name", typeof(Example), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) })),
typeof(object),
parameter);
// 将表达式树编译为委托
Func<object, object> compiledDelegate = Expression.Lambda<Func<object, object>>(dynamicExpression, parameter).Compile();
// 调用委托并输出结果
Console.WriteLine(compiledDelegate(obj)); // 输出:John Doe
}
}
代码说明:
1. 创建动态对象:使用 ExpandoObject 创建一个动态对象,并为其添加 Name 和 Age 属性。
2. 创建动态表达式树:
- Expression.Parameter 创建一个参数表达式,表示要操作的对象。
- Binder.GetMember 创建一个 GetMemberBinder,用于指定要调用的成员(Name 属性)。
- Expression.Dynamic 创建一个动态表达式,它接受 Binder、返回类型和参数表达式作为参数。
3. 编译表达式树:
- Expression.Lambda 创建一个 Lambda 表达式,它接受参数表达式和动态表达式作为参数。
- Compile 将 Lambda 表达式编译为委托。
4. 调用委托:
- 调用编译后的委托,并将动态对象作为参数传递。
- 委托返回 Name 属性的值。
Expression.Dynamic 允许您在运行时创建动态操作,这在处理动态类型或 COM 对象等场景中非常有用。通过使用 Binder,您可以指定要调用的成员或执行的操作,从而实现灵活的动态编程。