Быстрый доступ к типу / методу / ..., который содержит атрибут в C # - PullRequest
8 голосов
/ 28 августа 2009

Я сделал здесь собственный атрибут с именем AAtribute и, например, класс с именем B, в котором один или несколько методов используют этот атрибут. Можно ли получить MethodInfo метода, который содержит атрибут (в данном случае BMethod1) как (один из) его атрибутов, не проходя всю сборку и не просматривая все определенные методы для их атрибутов? И является ли их аналогом для других AttributeTargets (Параметры / Типы / Свойства / ...)? Я не хотел бы массив всех методов, которые используют этот тип атрибута, но только метод с этим объектом Attirbute в частности. Я хочу использовать его для наложения дополнительных ограничений на метод (тип возвращаемого значения, параметр, имя, другое использование атрибутов, ...).

[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

}

Ответы [ 3 ]

2 голосов
/ 28 августа 2009

Если я правильно понял ваш вопрос, вы хотите получить внутри кода атрибута объект (в данном случае метод), к которому применяется атрибут.
Я почти уверен, что прямого пути для этого не существует - атрибут не знает об объекте, к которому он прикреплен, эта ассоциация наоборот.

Лучшее, что я могу вам предложить, это обходной путь, подобный следующему:

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() {
        }
    }
}

Примечание
Чего вы хотите достичь, получая доступ к MethodInfo внутри конструктора атрибута? Может быть, есть альтернативный способ достичь своей цели ...

EDIT

В качестве другого возможного решения вы можете предоставить статический метод в вашем атрибуте, который выполняет проверку, но это включает в себя итерации по 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>();
        }
    }
}
2 голосов
/ 28 августа 2009

Я думаю, что ответ - нет. Или, по крайней мере, не в разумных пределах. Экземпляр атрибута создается только после того, как вы ищите атрибут через MethodInfo. Создание экземпляра класса, у которого есть метод с атрибутом, не будет создавать экземпляр атрибута. Экземпляры атрибутов создаются только после того, как вы начинаете копаться, чтобы найти их через отражение.

0 голосов
/ 28 августа 2009

Чтобы узнать, к какому методу применен атрибут, у вас уже есть 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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...