简体   繁体   中英

How to get Method Name of Generic Func<T> passed into Method

I'm trying to get the method name of a function passed into an object using a.Net closure like this:

Method Signature

public IEnumerable<T> GetData<T>(Func<IEnumerable<T>> WebServiceCallback) 
where T : class    
{
    // either gets me '<LoadData>b__3'
    var a = nrdsWebServiceCallback.Method.Name;
    var b = nrdsWebServiceCallback.GetInvocationList();

    return WebServiceCallback();
}

I'm calling it like this:

SessionStateService.Labs = CacheManager.GetData(() =>  
WCFService.GetLabs(SessionStateService.var1, SessionStateService.var2));

Seeing 'b__3' instead of WCFServce.GetLabs(..) etc

You're looking at the name of the lambda expression (generated by the compiler), instead of the name of the method called inside the lambda.

You have to use an <Expression<Func<T>> instead of a Func<T> . Expressions can be parsed and analyzed.

Try

public IEnumerable<T> GetData<T>(Expression<Func<IEnumerable<T>>> callbackExpression) 
where T : class    
{
    var methodCall = callbackExpression.Body as MethodCallExpression;
    if(methodCall != null)
    {
        string methodName = methodCall.Method.Name;
    }

    return callbackExpression.Compile()();
}

What is actually passed into your function is an anonymous lambda function ( () => WCFService.Etc ), so what you're seeing is the actual method name - <LoadData>b__3 is the autogenerated name for the anonymous method.

What you actually want is the method called inside the method called. For that, you need to delve into expressions. Instead of Func<IEnumerable<T>> , define your parameter as Expression<Func<IEnumerable<T>>> , and call this code:

var body = nrdsWebServiceCallback.Body as MethodCallExpression;
if (body != null)
   Console.WriteLine(body.Method.DeclaringType.Name + "." + body.Method.Name);

Here is another workaround:

Because you are using a callback (an anonymous function), and this is the way that its name is represented in the .Method.Name property.

You can use RegEx to fetch the name of the method from it:

/// <summary>
/// Gets a string between the characters '<' and '>' 
/// Which is the method name for anonymous methods.
/// </summary>
/// <param name="methodName"></param>
/// <returns>Simple method name</returns>
private static string GetMethodName(string methodName)
{
    var pattern = @"(?<=\<)(.*?)(?=\>)";
    var regex = new Regex(pattern);

    return regex.Match(methodName).Value;
}

It will take the string: <LoadData>b__3

And return the name of the function: LoadData

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM