如何将Lambda表达式分解为组成表达式的对象?

如何将Lambda表达式分解为组成表达式的对象?,lambda,expression,modelmetadata,Lambda,Expression,Modelmetadata,给出如下表达式: m=>m.Employee.Address.Line1 我需要创建一个函数,该函数可以遍历表达式,拉出所涉及的对象,或者至少是链中的最终对象(即上面的Address对象)。因此,对于上面的示例,函数将发现: “here”是m参数的实例(我可以从中获得类型) “here”是雇员成员的实例 (即,沿链条向下重复) 目的是能够生成“路径”的配置信息 如果我至少可以获得最终的“containing”对象,那么我可以生成类型信息,如果对象支持特定属性或方法,还可以调用该对象来请求该对

给出如下表达式:

m=>m.Employee.Address.Line1

我需要创建一个函数,该函数可以遍历表达式,拉出所涉及的对象,或者至少是链中的最终对象(即上面的Address对象)。因此,对于上面的示例,函数将发现:

  • “here”是m参数的实例(我可以从中获得类型)
  • “here”是雇员成员的实例
  • (即,沿链条向下重复)
目的是能够生成“路径”的配置信息

如果我至少可以获得最终的“containing”对象,那么我可以生成类型信息,如果对象支持特定属性或方法,还可以调用该对象来请求该对象的其他配置信息(以及获取容器类型配置信息的对象类型)

即使是稍微复杂一些的语句也会使这一点更加困难,例如:

m.Employee.Address[i]。第1行

---我只是想提供一个例子,说明我在MVC中为一个基本场景所做的工作。下面的GetContainingModel()在加载的DataAnnotationsMetadataProvider中的CreateMetadata()内调用。传递到CreateMetadata()的模型是Lambda语句根的模型,而不是我们想要的。因此,逻辑试图找到最终的包含对象。我不想像我现在做的那样使用反射,或者更糟糕的是,我想用反射来获得一个私人成员(糟糕),但是。。。我想听听你的建议

    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    private object GetContainingModel()
    {
        if (_metadata == null)
        {
            throw new SystemException("Unexpected NULL Metadata");
        }

        var model = _metadata.Model;

        try
        {
            if (_modelAccessor != null)
            {
                var data = _modelAccessor.Target;
                if (data != null)
                {
                    if (GetModelFromContainer(data, ref model))
                    {
                        GetModelFromExpression(data, ref model);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            var msg = ex.Message;
        }

        return model;
    }

    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    private bool GetModelFromContainer(object data, ref object model)
    {
        var isSet = false;

        var container = data.GetType().GetField("container");
        if (container != null)
        {
            model = container.GetValue(data);
            isSet = true;
        }
        else
        {
            var vdi = data.GetType().GetField("vdi");
            if (vdi != null)
            {
                var viewDataInfo = vdi.GetValue(data) as ViewDataInfo;
                if (viewDataInfo != null)
                {
                    model = viewDataInfo.Container;
                    isSet = true;
                }
            }
        }

        return isSet && model != null;
    }

    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    private bool GetModelFromExpression(object data, ref object model)
    {
        if (model == null)
            return false;

        var expressionField = data.GetType().GetField("expression");
        if (expressionField == null)
            return false;

        return GetModelFromExpression(expressionField.GetValue(data) as LambdaExpression, ref model);
    }

    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    private bool GetModelFromExpression(LambdaExpression sourceExpression, ref object model)
    {
        if (sourceExpression == null)
            return false;

        var expressionBody = sourceExpression.Body as MemberExpression;

        if (expressionBody == null || expressionBody.NodeType != ExpressionType.MemberAccess || expressionBody.Member == null)
            return false;


        var expression = expressionBody.Expression as MemberExpression;
        if (expression == null)
        {
            return false;
        }

        switch (expression.Member.MemberType)
        {
            case MemberTypes.Field:
                if (expression.NodeType == ExpressionType.MemberAccess)
                {
                    var fieldInfo = (FieldInfo)expression.Member;
                    if (fieldInfo != null)
                    {
                        model = fieldInfo.GetValue(model);
                    }
                }
                break;
            case MemberTypes.Property:
                var propertyInfo = (PropertyInfo)expression.Member;
                if (propertyInfo != null)
                {
                    model = propertyInfo.GetValue(model, null);
                }
                break;
        }

        return model != null;
    }

你有这方面的进展吗?这将是有用的张贴你在哪里与它还没有。谢谢包括利息。如果我发现任何信息,我会确保更新帖子。