I have the following class
public class MyClass
{
public bool Delete(Product product)
{
// some code.
}
}
Now I have a
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.
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();
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();
}
}