views:

779

answers:

3

Hi,

Sorry for the poor explaination of the problem

Totally rewriting question

I have the following method:

public TReturn FindCached<TSearch, TReturn>(Func<TSearch, TReturn> searchMethod) 
            where TSearch : ISearchSpecification
            where TReturn : class
        {
            SearchSpecification spec = new GetConcreteSearchSpecification<TSearch>();

            //insert magic here to get an attribute from the method on 
            //the spec class that searchMethod invokes on the line below

            return searchMethod(spec);
        }

So I have a delegate (searchMethod) and an object (spec) that I want to invoke the delegate on. I want to inspect the object (spec) to find a custom attribute on the method that searchMethod will call when invoked.

Hope this is clearer.

Thanks

+1  A: 

Assuming you meant searchMethod to be a variable of type Func<TSearch, TReturn> and mySearchSpec as some implementation of ISearchSpecification<TSearch>, then you are basically asking how to get attributes on a class.

For this, use something like:

object[] attrs = typeof(mySearchSpec).GetCustomAttributes(false);

Assuming that the mySearchSpec type is public, otherwise you may need a different overload for GetCustomAttributes

Addendum:
Based on your revised question, to get the attributes on a method on the actual type of spec used:

Type t = spec.GetType();
MethodInfo m = t.GetMethod("nameOfMethodToBeCalledHere");
object[] attrs = m.GetCustomAttributes(false);

Again, note that you may need overloads for GetMethod or GetCustomAttributes depending on the implementation of the actual class.

Note:
It does seem however like you might be asking for the method called in return searchMethod(spec);, but that is searchMethod and not some method on spec at all.

If you want attributes on searchMethod (nothing to do with spec):

MethodInfo m = searchMethod.Method;
object[] attrs = m.GetCustomAttributes(false);

I think that now covers all permutations of meaning...

jerryjvl
Thanks for your reply, I was unclear in my question: I'm actually trying to get a custom attribute from the method of the spec that searchMethod invokes.
Corin
Thanks again... my exact problem is getting "nameOfMethodToBeCalledHere" from the searchMethod FuncsearchMethod.Method.Name is populated with backing field stuff :(
Corin
You overshot your target by one property... see my latest note ;)
jerryjvl
attrs[0] comes back as System.Runtime.CompilerServices.CompilerGeneratedAttribute:(I'm not sure how this could work though as searchMethod is a function defined on an interface, not the concrete implementation that contains the custom attribute.
Corin
How do you mean, it's defined on the interface? ... the method you pass as the first parameter to 'FindCached' surely must be a concrete implementation? I think you are going to have an example of how you call this method to your question, because it is still not entirely clear what you are actually trying to do.
jerryjvl
A: 

This is quite a confusing question, let's see if I have it right:

  • You have a lambda function (which you describe as a delegate) called searchMethod.
  • You have a factory-pattern generated object called spec

So you have a method somewhere like this:

[MyCustomAttribute]
public RetClass MyMethod( SearchSpecification input ) {
    return input.GetRetClass();
}

And you call this method with:

var result = FindCached( MyMethod );

And in FindCached you want to find MyCustomAttribute - in that case @jerryjvl's answer is right.

Your problem is that you could also do:

var result = FindCached( x => x.GetRetClass() );

I'm not sure from your description whether it's an attribute on the x.GetRetClass() that you actually want. In this case you need to take the lambda apart using expressions, but I wouldn't recommend it - a more complex lambda declaration will result in an anonymous delegate, which is a black-box when you try to parse it at run time.

Instead, as you're using reflection anyway, it might be easier to pass the name of the method that you want instead of the delegate reference:

var result = FindCached( "GetRetClass" );
Keith
A: 

I ran into a similar situation, jerryjvl's answer explained exactly what I wanted.

I wanted to create a generic profiling method, where I could time how long some method took to run, and retrieve the name of the method using reflection for logging purposes.

The MethodInfo was the key.

Where I have a method like:

public static bool TimeMethod(Func<bool> someMethod)

And then later I want to dynamically get it's name or some attributes off it.

MethodInfo m = someMethod.Method;
object[] attrs = m.GetCustomAttributes(typeof(MonitoringDescriptionAttribute), true);
string name = m.Name;

Cheers

Mark