我有一个奇怪的情况,我需要将委托的名称作为字符串。我有一个看起来像这样的通用方法。
private T Get<T>(T task, Action<T> method) where T : class
{
string methodName = method.Method.Name //Should return Bark
}
我称之为
private void MakeDogBark()
{
dog = Get(dog, x=>x.Bark());
}
但我没有看到“树皮”,而是看到"<MakeDogBark>b__19"
。所以看起来它给了我初始调用的方法名称而不是委托的名称。
任何人都知道怎么做?
答案 0 :(得分:59)
它为您提供了代理的操作方法的名称。这恰好是使用lambda表达式实现的。
您目前有一个代理依次调用Bark。如果您想直接使用Bark
,则需要为Bark
方法创建一个开放代理,这可能不是非常简单。那是假设你真的想要打电话给它。如果您不需要调用它,或者知道它将在第一个参数上调用它,您可以使用:
private T Get<T>(T task, Action method) where T : class
{
string methodName = method.Method.Name //Should return Bark
}
private void MakeDogBark()
{
dog = Get(dog, dog.Bark);
}
你可以通过使参数成为表达式树而不是委托来解决这个问题,但是只有当lambda表达式只是一个方法调用时它才会起作用。
答案 1 :(得分:7)
您可以通过将参数设置为表达式而不是委托来获取方法调用的名称,就像Jon提到的那样
private T Get<T>(T task, Expression<Action<T>> method) where T : class
{
if (method.Body.NodeType == ExpressionType.Call)
{
var info = (MethodCallExpression)method.Body;
var name = info.Method.Name; // Will return "Bark"
}
//.....
}