表达式<func> issue </func>

时间:2011-01-07 16:34:50

标签: c# .net

我希望能够清楚简明地解释这一点。我有一个表达:

Expression<Func<TObject, TProperty>> expression

我正在尝试从中获取属性名称。一切都很好,花花公子'UNTIL',遇到转换表达式(在 GetPropertyName 方法 - 这是我想要排序问题的地方),即正常属性可能会出现{e =>e.EmployeeID}但是在少数情况下,我得到{e => Convert(e.EmployeeID)}的结果。这实际上意味着我无法识别正确的属性名称(我不想解析转换()等异常。)

如何将表达式名称干净地提取为属性。下面是我正在使用的代码,所以请随意篡改:

public static class ExpressionExtensions
{
    public static string GetPropertyName<TObject, TProperty>(
        this Expression<Func<TObject, TProperty>> expression) where TObject : class
    {
        if (expression.Body.NodeType == ExpressionType.Call)
        {
            MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body;
            string name = ExpressionExtensions.GetPropertyName(methodCallExpression);
            return name.Substring(expression.Parameters[0].Name.Length + 1);
        }
        return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
    }

    private static string GetPropertyName(MethodCallExpression expression)
    {
        MethodCallExpression methodCallExpression = expression.Object as MethodCallExpression;
        if (methodCallExpression != null)
        {
            return GetPropertyName(methodCallExpression);
        }
        return expression.Object.ToString();
    }
}

我正在调用它:

string propertyName = expression.GetPropertyName();
// which ideally should return a value of EmployeeID or ReportsTo
// as per the usage example below

这会影响一些仲裁用法,例如:

var tree = items2.AsHierarchy(e => e.EmployeeID, e => e.ReportsTo);

希望这能提供足够的信息让我脱离套索!!

欢呼声

2 个答案:

答案 0 :(得分:5)

您的表达式树中应该有一个“转换”节点,因此您应该测试nodetype为“convert”的节点,然后如果为true,则在转换为字符串之前更深一级。尝试这样的事情:

        public static string GetMemberName<TSource,TMember>(this Expression<Func<TSource,TMember>> memberReference)
    {
        MemberExpression expression = memberReference.Body as MemberExpression;
        if (expression == null)
        {
            UnaryExpression convertexp = memberReference.Body as UnaryExpression;
            if(convertexp!=null)
            expression = convertexp.Operand as MemberExpression; ;
        }
        if(expression==null)
            throw new ArgumentNullException("memberReference");

        return expression.Member.Name;
    }

答案 1 :(得分:3)

您是否有{e => Convert(e.EmployeeID)}操作的示例?

我猜Convert是一个装箱操作,即它采用的是值类型(大概是int?)并转换为object。如果是这样,并且从int转换为object是正确的做法,Convert是不可避免的;你应该用你的GetPropertyName方法解决它。