Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

generics

func

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

like image 506
Barry McDermid Avatar asked Dec 06 '13 09:12

Barry McDermid


2 Answers

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()();
}
like image 82
dcastro Avatar answered Oct 27 '22 01:10

dcastro


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);
like image 37
Avner Shahar-Kashtan Avatar answered Oct 27 '22 00:10

Avner Shahar-Kashtan