是否可以从动作中获取方法名称?我知道我总是可以传递一个字符串,但我希望能有更聪明的东西。
public bool DeviceCommand(Action apiCall)
{
//It would be nice to log the method name that was passed in
try
{
apiCall();
}
catch (Exception exc)
{
LogException(exc);
return false;
}
return true;
}
用法如下:
void MyMethod()
(
DeviceCommand(() => api.WriteConfig(config));
)
答案 0 :(得分:21)
如果您对DeviceCommand的调用总是将采用
形式DeviceCommand(() => someObject.SomeMethod(parameters));
然后您可以修改DeviceCommand以将表达式树作为参数。这将允许您深入到树中以获取所需的信息(在本例中为字符串“SomeMethod”),然后将树编译为委托并执行它:
public bool DeviceCommand(Expression<Action> apiCallExp)
{
var methodCallExp = (MethodCallExpression) apiCallExp.Body;
string methodName = methodCallExp.Method.Name;
// do whatever you want with methodName
Action apiCall = apiCallExp.Compile();
try
{
apiCall();
}
catch(Exception exc)
{
LogException(exc);
return false;
}
return true;
}
当然,每次构建和编译表达式树都可能是一个主要的性能问题(或者不是 - 它只取决于调用DeviceCommand
的频率)。在你的情况下,你必须决定性能影响(以及这种方法的一般“黑客”是否值得)。
答案 1 :(得分:19)
是的,有:Action.Method.Name
但是,这仅在将Action参数作为方法组传递而不是作为lambda表达式传递时才有效:
class Program
{
static void SomeActionName(){}
static void Main(string[] args)
{
LogMethodName(() => SomeActionName()); // <Main>b__0
LogMethodName(SomeActionName); // SomeActionName
var instance = new SomeClass();
LogMethodName(() => instance.SomeClassMethod());; // <Main>b__1
LogMethodName(instance.SomeClassMethod); // SomeClassMethod
}
private static void LogMethodName(Action action)
{
Console.WriteLine(action.Method.Name);
}
}
class SomeClass
{
public void SomeClassMethod(){}
}