Access the value of a member expression

前端 未结 9 2090
滥情空心
滥情空心 2020-12-04 08:33

If i have a product.

var p = new Product { Price = 30 };

and i have the following linq query.

var q = repo.Products().Where         


        
9条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-04 08:59

    As of 2020

    This helper method will gracefully retrieve any expression value, without "compiling hack" :

    public static object GetMemberExpressionValue (MemberExpression expression)
    {
        // Dependency chain of a MemberExpression is of the form:
        // MemberExpression expression
        //    MemberExpression expression.Expression
        //        ... MemberExpression expression.[...].Expression
        //            ConstantExpression expression.[...].Expression.Expression <- base object
        var dependencyChain = new List();
        var pointingExpression = expression;
        while (pointingExpression != null)
        {
            dependencyChain.Add(pointingExpression);
            pointingExpression = pointingExpression.Expression as MemberExpression;
        }
    
        if (!(dependencyChain.Last().Expression is ConstantExpression baseExpression))
        {
            throw new Exception(
                $"Last expression {dependencyChain.Last().Expression} of dependency chain of {expression} is not a constant." +
                "Thus the expression value cannot be found.");
        }
    
        var resolvedValue = baseExpression.Value;
    
        for (var i = dependencyChain.Count; i > 0; i--)
        {
            var expr = dependencyChain[i - 1];
            resolvedValue = new PropOrField(expr.Member).GetValue(resolvedValue);
        }
    
        return resolvedValue;
    }
    

    PropOrField class :

    public class PropOrField
    {
        public readonly MemberInfo MemberInfo;
    
        public PropOrField (MemberInfo memberInfo)
        {
            if (!(memberInfo is PropertyInfo) && !(memberInfo is FieldInfo))
            {
                throw new Exception(
                    $"{nameof(memberInfo)} must either be {nameof(PropertyInfo)} or {nameof(FieldInfo)}");
            }
    
            MemberInfo = memberInfo;
        }
    
        public object GetValue (object source)
        {
            if (MemberInfo is PropertyInfo propertyInfo) return propertyInfo.GetValue(source);
            if (MemberInfo is FieldInfo fieldInfo) return fieldInfo.GetValue(source);
    
            return null;
        }
    
        public void SetValue (object target, object source)
        {
            if (MemberInfo is PropertyInfo propertyInfo) propertyInfo.SetValue(target, source);
            if (MemberInfo is FieldInfo fieldInfo) fieldInfo.SetValue(target, source);
        }
    
        public Type GetMemberType ()
        {
            if (MemberInfo is PropertyInfo propertyInfo) return propertyInfo.PropertyType;
            if (MemberInfo is FieldInfo fieldInfo) return fieldInfo.FieldType;
    
            return null;
        }
    }
    

提交回复
热议问题