Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fast Access to the type/method/... that holds an Attribute in C#

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

}
like image 848
Willem Van Onsem Avatar asked Aug 28 '09 09:08

Willem Van Onsem


2 Answers

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>();
        }
    }
}
like image 111
Paolo Tedesco Avatar answered Sep 27 '22 19:09

Paolo Tedesco


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.

like image 22
Mike Two Avatar answered Sep 27 '22 18:09

Mike Two