简单的解决方案:(从下面的 leppie 偷来的)
只需从 GetCached 方法中删除第二个参数:
ReturnType GetCached(Func<T> func)
{
var name = func.Method.Name;
// execute func here
}
假设它会被这样调用:
GetCached(BLCustomer.GetAll);
不是这样的:
GetCached(() => BLCustomer.GetAll());
复杂的解决方案:
你可以这样做:
string GetMethodName(Expression<Func<Func<dynamic>>> methodExpression)
{
dynamic memberExpression = methodExpression.Body;
MethodInfo result = memberExpression.Operand.Arguments[2].Value;
return result.Name;
}
这样称呼它:
GetCached(BLCustomer.GetSingle, GetMethodName(() => BLCustomer.GetSingle));
这种方法做了两个假设:
- 调用总是需要像示例中的那样,即它不能有参数,并且委托的主体必须只包含您想要名称的方法,而不是其他任何东西
- 您想要命名的方法不能是
void 类型并且不能有任何参数。
您也可以将其用于非静态方法:
BLCustomer customer = new BLCustomer();
GetCached(customer.GetSingle, GetMethodName(() => customer.GetSingle));
您甚至可以将 GetCached 更改为以下内容以清理其 API:
ReturnType GetCached<T>(Expression<Func<Func<T>>> methodExpression)
{
var name = GetMethodName(methodExpression);
var func = methodExpression.Compile()();
// execute func and do stuff
}
为此,您需要将GetMethodName 设为通用,而不是使用dynamic:
string GetMethodName<T>(Expression<Func<Func<T>>> methodExpression)
{
dynamic memberExpression = methodExpression.Body;
MethodInfo result = memberExpression.Operand.Arguments[2].Value;
return result.Name;
}
然后你可以这样称呼它:
GetCached<IEnumerable<Customer>>(() => BLCustomer.GetAll)
GetCached<Customer>(() => BLCustomer.GetSingle)