SIMPLE SOLUTION: (stolen from leppie below)
Simply remove the second parameter from your GetCached
method:
ReturnType GetCached(Func<T> func)
{
var name = func.Method.Name;
// execute func here
}
This assumes, that it will be called like this:
GetCached(BLCustomer.GetAll);
and not like this:
GetCached(() => BLCustomer.GetAll());
COMPLEX SOLUTION:
You can do it like this:
string GetMethodName(Expression<Func<Func<dynamic>>> methodExpression)
{
dynamic memberExpression = methodExpression.Body;
MethodInfo result = memberExpression.Operand.Arguments[2].Value;
return result.Name;
}
Call it like this:
GetCached(BLCustomer.GetSingle, GetMethodName(() => BLCustomer.GetSingle));
This approach makes two assumptions:
- The call always needs to look like in the example, i.e. it mustn't have a parameter and the body of the delegate must contain only the method you want the name from and nothing else
- The method you want the name from must not be of type
void
and must not have any parameters.
You can use this also for non static methods:
BLCustomer customer = new BLCustomer();
GetCached(customer.GetSingle, GetMethodName(() => customer.GetSingle));
You can even change GetCached
to the following to cleanup its API:
ReturnType GetCached<T>(Expression<Func<Func<T>>> methodExpression)
{
var name = GetMethodName(methodExpression);
var func = methodExpression.Compile()();
// execute func and do stuff
}
For this to work, you need to make GetMethodName
generic instead of using dynamic
:
string GetMethodName<T>(Expression<Func<Func<T>>> methodExpression)
{
dynamic memberExpression = methodExpression.Body;
MethodInfo result = memberExpression.Operand.Arguments[2].Value;
return result.Name;
}
And then you can call it like this:
GetCached<IEnumerable<Customer>>(() => BLCustomer.GetAll)
GetCached<Customer>(() => BLCustomer.GetSingle)