Get the parameter value from a Linq Expression

前端 未结 3 575
别跟我提以往
别跟我提以往 2021-01-01 16:21

I have the following class

public class MyClass
{
    public bool Delete(Product product)
    {
        // some code.
    }
}

Now I have a

相关标签:
3条回答
  • 2021-01-01 16:39

    Here is an example of creation of a delegate using a lambda. The object instance is encapsulated into the delegate using a C# feature called closure.

    MyClass instance = new MyClass();
        //This following line cannot be changed to var declaration 
        //since C# can't infer the type.
    Func<Product, bool> deleteDelegate = p => instance.Delete(p);
    Product product = new Product();
    bool deleted = deleteDelegate(product);
    

    Alternatively you are trying to create a Helper that automagically Currys.

    public class Helper<T>
        where T : new()
    {
        public TResult Execute<TResult>(Func<T, TResult> methodLambda)
        {
            var instance = new T();
            return methodLamda(instance);
        }
    }
    
    public void Main()
    {
        var helper = new Helper<MyClass>();
        var product = new Product();
        helper.Execute(x => x.Delete(product));
    }
    

    However I have to say this problem looks suspiciously like the creation of a Helper class to handle the lifetime of a WCF proxy....You know...just say...in which case this ISN'T how I would approach this...simply because this approach leaks WCF specific code into your domain.

    0 讨论(0)
  • 2021-01-01 16:43

    You can compile the argument expression and then invoke it to calculate the value:

    var values = new List<object>();
    foreach(var arg in body.Arguments)
    {
        var value = Expression.Lambda(argument).Compile().DynamicInvoke();
        values.Add(value);
    }
    this.ArgValues = values.ToArray();
    
    0 讨论(0)
  • 2021-01-01 17:01

    This method works pretty well. It returns the argument types and values for an Expression>

        private static KeyValuePair<Type, object>[] ResolveArgs<T>(Expression<Func<T, object>> expression)
        {
            var body = (System.Linq.Expressions.MethodCallExpression)expression.Body;
            var values = new List<KeyValuePair<Type, object>>();
    
            foreach (var argument in body.Arguments)
            {
                var exp = ResolveMemberExpression(argument);
                var type = argument.Type;
    
                var value = GetValue(exp);
    
                values.Add(new KeyValuePair<Type, object>(type, value));
            }
    
            return values.ToArray();
        }
    
        public static MemberExpression ResolveMemberExpression(Expression expression)
        {
    
            if (expression is MemberExpression)
            {
                return (MemberExpression)expression;
            }
            else if (expression is UnaryExpression)
            {
                // if casting is involved, Expression is not x => x.FieldName but x => Convert(x.Fieldname)
                return (MemberExpression)((UnaryExpression)expression).Operand;
            }
            else
            {
                throw new NotSupportedException(expression.ToString());
            }
        }
    
        private static object GetValue(MemberExpression exp)
        {
            // expression is ConstantExpression or FieldExpression
            if (exp.Expression is ConstantExpression)
            {
                return (((ConstantExpression)exp.Expression).Value)
                        .GetType()
                        .GetField(exp.Member.Name)
                        .GetValue(((ConstantExpression)exp.Expression).Value);    
            }
            else if (exp.Expression is MemberExpression)
            {
                return GetValue((MemberExpression)exp.Expression);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
    
    0 讨论(0)
提交回复
热议问题