C# 表达式树 Expression.Dynamic 用法示例

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,您可以指定要调用的成员或执行的操作,从而实现灵活的动态编程。

评论