views:

249

answers:

3

I have made a custom Attribute here named AAtribute, and for instance a class called B where one or more methods use the attribute. Is it possible to get the MethodInfo of the method that holds the attribute (in this case BMethod1) as (one of) it's attributes without walking through the whole assembly and looking at all defined methods for their attributes? And is their an analogue way for other AttributeTargets (Parameters/Types/Properties/...)? I'don't want an array of all Methods that use that type of Attribute, but just the method with this Attirbute-object in particual. I want to use it to put additional constraints on the method (Return type, parameter, name, other Attribute-usage,...).

[AttributeUsage(AttributeTargets.Method)]
public class AAtribute : Attribute {

    //some fields and properties

    public AAtribute () {//perhaps with some parameters
        //some operations
        MethodInfo mi;//acces to the MethodInfo with this Attribute
                      //as an Attribute (the question)
        //some operations with the MethodInfo
    }

    //some methods

}

public class B {

    //some fields, properties and constructors

    [A]
    public void BMethod1 () {
        //some operations
    }

    //other methods

}
A: 

To find out if a method has an attribute applied to it, you already have the MethodInfo.

var type = obj.GetType();
foreach(var method in type.GetMethods())
{
    var attributes = method.GetCustomAttributes(typeof(AAtribute));
    if(attributes.Length > 0)
    {
        //this method has AAtribute applied at least once
    }
}

nexus
Yeah, but how do you do it from inside the attribute ? Is there a way to know which method (or member) the current instance of the attribute is applied to ?
Thomas Levesque
A: 

If I understood correctly your question, you want to get, inside the attribute code, the object (a method in this case) to which the attribute is applied.
I'm pretty sure there is no direct way to do this - the attribute has no knowledge of the object to which it is attached, this association is the other way round.

The best I can suggest you is a workaround like the following:

using System;
using System.Reflection;

namespace test {

    [AttributeUsage(AttributeTargets.Method)]
    public class AAttribute : Attribute {
        public AAttribute(Type type,string method) {
            MethodInfo mi = type.GetMethod(method);
        }
    }

    public class B {
        [A(typeof(B),"BMethod1")]
        public void BMethod1() {
        }
    }
}

NOTE
What do you want to achieve by accessing the MethodInfo inside the attribute's constructor? Maybe there's an alternative way to obtain your goal...

EDIT

As another possible solution, you might provide a static method in your attribute that does the checking - but this involves iterating over the MethodInfos.

using System;
using System.Reflection;
namespace test {

    [AttributeUsage(AttributeTargets.Method)]
    public class AAttribute : Attribute {
        public static void CheckType<T>() {
            foreach (MethodInfo mi in typeof(T).GetMethods()) {
                AAttribute[] attributes = (AAttribute[])mi.GetCustomAttributes(typeof(AAttribute), false);
                if (0 != attributes.Length) {
                    // do your checks here
                }
            }
        }
    }

    public class B {
        [A]
        public void BMethod1() {
        }
        [A]
        public int BMethod2() {
            return 0;
        }
    }

    public static class Program {
        public static void Main() {
            AAttribute.CheckType<B>();
        }
    }
}
Paolo Tedesco
Like I already said, I want to put additiol constraints on it (return type, number of parameters, types of parameters, name of the method,...). If the method isn't valid an Exception could be thrown. But whatever the reason is, wouldn't it be logic that you can access the thing where the attribute is linked at?
CommuSoft
Yes, but what do you want to do with those constraints? The attribute will not be instantiated until you try to reflect the type, in any case.
Paolo Tedesco
+1  A: 

I think the answer is no. Or at least not in a reasonable way. The instance of the attribute is only constructed once you look for the attribute through the MethodInfo. Instantiating the class that has the method that has the attribute will not instantiate the attribute. Attribute instances are only created once you start poking around to find them through reflection.

Mike Two