Отражение - получить имя атрибута и значение свойства - PullRequest
209 голосов
/ 10 июля 2011

У меня есть класс, давайте назовем его Book со свойством Name. С этим свойством у меня есть атрибут, связанный с ним.

public class Book
{
    [Author("AuthorName")]
    public string Name
    {
        get; private set; 
    }
}

В моем основном методе я использую отражение и хочу получить пару значений ключа каждого атрибута для каждого свойства. Поэтому в этом примере я ожидаю увидеть «Author» для имени атрибута и «AuthorName» для значения атрибута.

Вопрос: Как получить имя и значение атрибута в моих свойствах с помощью Reflection?

Ответы [ 14 ]

0 голосов
/ 25 июня 2018

Просто ищем подходящее место для размещения этого кода.

Допустим, у вас есть следующее свойство:

[Display(Name = "Solar Radiation (Average)", ShortName = "SolarRadiationAvg")]
public int SolarRadiationAvgSensorId { get; set; }

И вы хотите получить значение ShortName.Вы можете сделать:

((DisplayAttribute)(typeof(SensorsModel).GetProperty(SolarRadiationAvgSensorId).GetCustomAttribute(typeof(DisplayAttribute)))).ShortName;

Или сделать его общим:

internal static string GetPropertyAttributeShortName(string propertyName)
{
    return ((DisplayAttribute)(typeof(SensorsModel).GetProperty(propertyName).GetCustomAttribute(typeof(DisplayAttribute)))).ShortName;
}
0 голосов
/ 09 января 2018

чтобы получить атрибут из enum, я использую:

 public enum ExceptionCodes
 {
  [ExceptionCode(1000)]
  InternalError,
 }

 public static (int code, string message) Translate(ExceptionCodes code)
        {
            return code.GetType()
            .GetField(Enum.GetName(typeof(ExceptionCodes), code))
            .GetCustomAttributes(false).Where((attr) =>
            {
                return (attr is ExceptionCodeAttribute);
            }).Select(customAttr =>
            {
                var attr = (customAttr as ExceptionCodeAttribute);
                return (attr.Code, attr.FriendlyMessage);
            }).FirstOrDefault();
        }

// Используя

 var _message = Translate(code);
0 голосов
/ 28 марта 2017

Вот некоторые статические методы, которые вы можете использовать для получения MaxLength или любого другого атрибута.

using System;
using System.Linq;
using System.Reflection;
using System.ComponentModel.DataAnnotations;
using System.Linq.Expressions;

public static class AttributeHelpers {

public static Int32 GetMaxLength<T>(Expression<Func<T,string>> propertyExpression) {
    return GetPropertyAttributeValue<T,string,MaxLengthAttribute,Int32>(propertyExpression,attr => attr.Length);
}

//Optional Extension method
public static Int32 GetMaxLength<T>(this T instance,Expression<Func<T,string>> propertyExpression) {
    return GetMaxLength<T>(propertyExpression);
}


//Required generic method to get any property attribute from any class
public static TValue GetPropertyAttributeValue<T, TOut, TAttribute, TValue>(Expression<Func<T,TOut>> propertyExpression,Func<TAttribute,TValue> valueSelector) where TAttribute : Attribute {
    var expression = (MemberExpression)propertyExpression.Body;
    var propertyInfo = (PropertyInfo)expression.Member;
    var attr = propertyInfo.GetCustomAttributes(typeof(TAttribute),true).FirstOrDefault() as TAttribute;

    if (attr==null) {
        throw new MissingMemberException(typeof(T).Name+"."+propertyInfo.Name,typeof(TAttribute).Name);
    }

    return valueSelector(attr);
}

}

Использование статического метода ...

var length = AttributeHelpers.GetMaxLength<Player>(x => x.PlayerName);

Или использование необязательногометод расширения для экземпляра ...

var player = new Player();
var length = player.GetMaxLength(x => x.PlayerName);

Или использование полностью статического метода для любого другого атрибута (например, StringLength) ...

var length = AttributeHelpers.GetPropertyAttributeValue<Player,string,StringLengthAttribute,Int32>(prop => prop.PlayerName,attr => attr.MaximumLength);

Вдохновлено ответом Микаэля Энгвера.

0 голосов
/ 03 февраля 2017
foreach (var p in model.GetType().GetProperties())
{
   var valueOfDisplay = 
       p.GetCustomAttributesData()
        .Any(a => a.AttributeType.Name == "DisplayNameAttribute") ? 
            p.GetCustomAttribute<DisplayNameAttribute>().DisplayName : 
            p.Name;
}

В этом примере я использовал DisplayName вместо Author, потому что у него есть поле с именем 'DisplayName', которое должно отображаться со значением.

...