Страницы

Поиск по вопросам

понедельник, 6 января 2020 г.

Как достучаться до свойств атрибута?

#c_sharp


У меня есть Type атрибута. Я разбираю Assembly по типам, которые имеют нужный атрибут.

types = ass.GetTypes().Where(t => t.CustomAttributes.Any(a => a.AttributeType ==
utilTypes[1]));


То есть получаю список типов. Мне нужно, перебирая этот список, достать свойства
атрибута. Ну например вот из этого

[MyAttribute("Hello")]
class MyClass{}


мне нужно достать свойство Prop1, которое равно "Hello". Как это сделать? Чего то
уже совсем запутался в этих рефлекциях :(

UPD1

Забыл сказать. У меня нет прямого доступа к типу атрибута. То есть я не могу сделать так

foreach (var type in types)
{
    var MyAttr = (MyAttributeAttribute)type.GetCustomAttribute(utilTypes[0].GetType())
}


Потому что этот самый тип атрибута MyAttributeAttribute я имею только в текстовом
виде. А значит мне нужно каким то образом достать из него свойство, к которому я не
имею прямой доступ
    


Ответы

Ответ 1



Попробуйте следующий подход. Пусть тип экземпляра класса MyClass лежит в переменной type. То есть: Type type = typeof(MyClass); Или в вашем случае: Type type = types[i]; Тогда следующий код: var attr = type.CustomAttributes.FirstOrDefault(a => a.AttributeType == utilTypes[0]); if (attr != null) { var attrType = attr.AttributeType; var propInfo = attrType.GetProperty("Prop1", BindingFlags.Instance | BindingFlags.Public); Console.WriteLine(propInfo.GetValue(mcType.GetCustomAttribute(attrType))); } Выведет: Hello Вот, оформил в виде метода: public static object GetAttributeProperty(Type classType, Type attributeType, string propertyName) { var propInfo = attributeType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public); return propInfo.GetValue(classType.GetCustomAttribute(attributeType)); }

Ответ 2



Воспользуйтесь функцией GetProperty у класса Type Например так foreach (var type in types) { System.Reflection.PropertyInfo propertyInfo = type.GetProperty(<Имя свойства>, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) if(propertyInfo != null) { // свойство с таким именем найдено } } Найдя свойство, из структуры System.Reflection.PropertyInfo можно получить и значение свойства, и тип... дело техники уже

Ответ 3



Как-то так: using System; using System.Linq; using System.Reflection; class Program { class MyAttributeAttribute : Attribute { public string MyProperty { get; private set; } public MyAttributeAttribute(string myProp) { MyProperty = myProp; } } [MyAttribute("Hello")] class TestClass { } static void Main() { Assembly ass = Assembly.GetExecutingAssembly(); var types = ass.GetTypes().Where(t => t.CustomAttributes.Any(a => a.AttributeType.Name == "MyAttributeAttribute")); foreach (var type in types) { var ma = type.GetCustomAttributes().FirstOrDefault((a) => { return a.GetType().Name == "MyAttributeAttribute"; }); if (ma == null) continue; var prop = ma.GetType().GetProperty("MyProperty"); if (prop == null) continue; string str = prop.GetValue(ma).ToString(); // --> Hello } } }

Ответ 4



Если параметр обязательный - то проще всего получить его значение вот так: var attr = type.CustomAttributes.Single(a => a.AttributeType.FullName == "My.Namespace.MyAttribute"); Console.WriteLine(attr.ConstructorArguments[0]);

Ответ 5



А как же статическая типизация? Добавьте интерфейс, который реализует необходимое вам свойство, ищите типы, которые его имплементируют, инстанциируйте их экземпляры и приведите к интерфейсу.

Комментариев нет:

Отправить комментарий