Expression

//问题描述 我想写一个递归 是刚刚看了作者的文章 试着写一下 但是调用时 出现了问题 代码如下

 People PeopleModels = new People() { 
            ID="12345",
            Name="father",
            ParentID="",
                Child=new People[1]{
                    new People(){           
                    ID="12",
                    Name="erzi12",
                    ParentID="123456",
                    Child=null
                    } 
                }
            };
            Func<People, List<People>> ListPeople = null;
            Expression<Func<People, List<People>>> ListFuncExp = i => ListPeople(i);
            ParameterExpression parameter = Expression.Parameter(typeof(People), "Models");
            var DiGui = Expression.Lambda<Func<People, List<People>>>(
                Expression.Block(
                    new ParameterExpression[] { parameter },//var Models;
                    Expression.Assign(parameter, Expression.Constant(PeopleModels)),//Models=PeopleModels
                    Expression.IfThenElse(//if
                        Expression.AndAlso(//Models.ParentID=="" && Models.Child.Length==0
                            Expression.Equal(
                            Expression.MakeMemberAccess(parameter, typeof(People).GetProperty("ParentID")),
                            Expression.Constant("")),
                            //========================
                            Expression.Equal(
                            Expression.ArrayLength(Expression.MakeMemberAccess(parameter, typeof(People).GetProperty("Child"))),
                            Expression.Constant(0))
                        ),
                        Expression.Block(//iftrue Console.WriteLine(new List<People>(){Models})
                            Expression.Call(null, typeof(Console).GetMethod("WriteLine", new[] { typeof(List<People>) }),
                                Expression.ListInit(
                                    Expression.New(//new List<People>(){}
                                       typeof(List<People>).GetConstructor(new Type[0])),
                                       Expression.ElementInit(typeof(List<People>).GetMethod("Add"),parameter
                                    )
                                )
                            )
                        ), 
                        //else
                        Expression.Invoke(ListFuncExp, parameter)//调用ListFuncExp(parameter)
                        ), Expression.Invoke(ListFuncExp, parameter)
                    ),new ParameterExpression[] { parameter }
                 );
            var resultDiguis = DiGui.Compile();
            //问题 这里如果调用resultDiguis(PeopleModels) 会报错 未将对象引用到对象的实例???
            Console.WriteLine("结果:{0}", resultDiguis);

PeopleModels 变量在定义时赋予了一个 People 对象,但是在后面的代码中,又定义了一个同名的参数 parameter,导致了变量重复定义的错误。
People 类中的 Child 属性是一个 People 数组,但是在给 Child 赋值时使用了 new People[1] 这种语法,这是错误的。正确的写法应该是 new People[]{...}。
在 Lambda 表达式的 Body 中,调用 Console.WriteLine 方法时使用了错误的语法。应该使用 Expression.Call 方法来调用方法。
如果要实现递归的效果,就需要在调用自身的时候传入当前要遍历的对象,而代码中并没有这么做。
望采纳。

  • ① 在定义 PeopleModels 变量时,应该使用 People 类型而不是 PeopleModels,因为后者并没有定义:
People peopleModels = new People() { 
  • ② 在定义 ListFuncExp 变量时,应使用 List 类型而不是 Func<People, List> 类型:
Expression<Func<People, List<People>>> listFuncExp = i => ListPeople(i);
  • ③ 在调用 Console.WriteLine 方法时,应将要输出的参数作为方法的第一个参数,而不是第二个参数:
Expression.Call(null, typeof(Console).GetMethod("WriteLine", new[] { typeof(object) }),
  • ④ 你还需要保证 ListPeople 变量已被正确赋值,否则调用时会抛出异常。
  • ⑤ 你可能需要更新代码中的类型名称,例如改为 People 而不是 Models。