2014-10-14 2 views
3

Существующий код (упрощенный)Получение Атрибут Описание недвижимости

У меня эту функцию

public static string[] GetFieldNames<T>(IEnumerable<T> items) 
    where T : class 
{ 
    var properties = typeof(T).GetProperties().Where(p => SystemTypes.Contains(p.PropertyType)); // Only get System types 

    return properties.Select(p => p.Name).ToArray(); 
} 

Так что, если у меня есть этот класс

class MyClass { 
    public string Name { get; set; } 

    [Description("The value")] 
    public int Value { get; set; } 
} 

я могу иметь код, как этот

List<MyClass> items = ...; // Populate items somehow 
string[] fieldNames = GetFieldNames(items); // This returns ["Name", "Value"] 

Это прекрасно работает.

Проблема

Мне нужно, чтобы получить описание (если она существует), так что GetFieldNames(items) возвращает ["Name", "The value"]

Как изменить функцию GetFieldNames() прочитать описание атрибута, если он существует?
(Пожалуйста, обратите внимание, что эта функция была упрощена, реальная функция является гораздо более сложным, так что пожалуйста, не меняя логики)

+0

Что это возвращение сейчас, и что вам нужно сделать по-другому? Вы хотите вернуть «Словарь» вместо строкового массива? – AdamMc331

+0

McAdams331, вы прочитали вопрос? Я не уверен, как я могу сделать это яснее. Нет, он все равно будет строковым массивом (подпись функции не должна меняться) – Aximili

ответ

3

Это должно работать для вас:

return properties.Select(p => 
    Attribute.IsDefined(p, typeof(DescriptionAttribute)) ? 
     (Attribute.GetCustomAttribute(p, typeof(DescriptionAttribute)) as DescriptionAttribute).Description: 
     p.Name 
    ).ToArray(); 
3

ПРИМЕЧАНИЕ: просто добавить using System.Reflection, как это GetCustomAttribute метод расширения в .NET 4,5

public static Tuple<string,string>[] GetFieldNames<T>(IEnumerable<T> items) where T : class 
{ 
    var result = 
     typeof (T).GetProperties() 
      .Where(p => SystemTypes.Contains(p.PropertyType) &&p.GetCustomAttribute<DescriptionAttribute>() != null) 
      .Select(
       p => 
        new Tuple<string, string>(p.Name, 
         p.GetCustomAttribute<DescriptionAttribute>().Description)); 

    return result.ToArray(); 
} 

за ранее версия платформы .NET мы можем использовать этот метод расширения:

public static class Extension 
{ 
    public static T GetCustomAttribute<T>(this System.Reflection.MemberInfo mi) where T : Attribute 
    { 
     return mi.GetCustomAttributes(typeof (T),true).FirstOrDefault() as T; 
    } 
} 
+0

Спасибо, это выглядит красиво, но есть ошибка: «System.Reflection.PropertyInfo» не содержит определения для «GetCustomAttribute» – Aximili

+0

'GetCustomAttribute '- это метод расширения в' System.Reflection' в .Net 4.5 и выше – user3473830

0

использование GetCustomAttributes Метод

static void attributecheck() 
    { 
     var props = typeof(Product).GetProperties(); 
     foreach (var propertyInfo in props) 
     { 
      var att = propertyInfo.GetCustomAttributes(typeof(DescriptionAttribute), true); 
      if (att.Length >0) 
      { 
      } 
     } 
    } 
0

Это общая функция, которую вы можете использовать, если fieldName имеет description атрибут тега его вернуть значение в противном случае оно возвращает null.

public string GetDescription<T>(string fieldName) 
{ 
    string result; 
    FieldInfo fi = typeof(T).GetField(fieldName.ToString()); 
    if (fi != null) 
    { 
     try 
     { 
      object[] descriptionAttrs = fi.GetCustomAttributes(typeof(DescriptionAttribute), false); 
      DescriptionAttribute description = (DescriptionAttribute)descriptionAttrs[0]; 
      result = (description.Description); 
     } 
     catch 
     { 
      result = null; 
     } 
    } 
    else 
    { 
     result = null; 
    } 

    return result; 
} 

Пример:

class MyClass { 
    public string Name { get; set; } 

    [Description("The age description")] 
    public int Age { get; set; } 
} 

string ageDescription = GetDescription<MyClass>("age"); 
console.log(ageDescription) // OUTPUT: The age description