2009-03-30 5 views
12

Jak uzyskać dostęp do właściwości Opis albo na const lub mienia, tjJak uzyskać dostęp do atrybutu Opis na właściwości lub const w C#?

public static class Group 
{ 

    [Description("Specified parent-child relationship already exists.")] 
    public const int ParentChildRelationshipExists = 1; 

    [Description("User is already a member of the group.")] 
    public const int UserExistsInGroup = 2; 

} 

lub

public static class Group 
{ 

    [Description("Specified parent-child relationship already exists.")] 
    public static int ParentChildRelationshipExists { 
     get { return 1; } 
    } 

    [Description("User is already a member of the group.")] 
    public static int UserExistsInGroup { 
     get { return 2; } 
    } 

} 

W klasie wywołującego Chciałbym uzyskać dostęp do właściwości opis, to znaczy,

int x = Group.UserExistsInGroup; 
string description = Group.UserExistsInGroup.GetDescription(); // or similar 

Jestem otwarty na pomysły także dla innych metodologii.

EDIT: Powinienem wspomnieć, że widziałem przykładem warunkiem tutaj: Do auto-implemented properties support attributes?

jednak szukam sposobu uzyskania dostępu do atrybut opis bez konieczności podawania ciąg dosłownego do typu nieruchomości, tj. wolałbym tego nie robić:

typeof(Group).GetProperty("UserExistsInGroup"); 

Coś podobnego do metody rozszerzającej; podobna do następującej metody, która zwróci atrybut Opis na enum poprzez metodę rozszerzenia:

public static String GetEnumDescription(this Enum obj) 
{ 
    try 
    { 
     System.Reflection.FieldInfo fieldInfo = 
      obj.GetType().GetField(obj.ToString()); 

     object[] attribArray = fieldInfo.GetCustomAttributes(false); 

     if (attribArray.Length > 0) 
     { 
      var attrib = attribArray[0] as DescriptionAttribute; 

      if(attrib != null ) 
       return attrib.Description; 
     } 
     return obj.ToString(); 
    } 
    catch(NullReferenceException ex) 
    { 
     return "Unknown"; 
    } 
} 
+0

W odpowiedzi na Pana EDIT: Zobacz ten http://www.codeproject.com/Articles/28514/Strong-Reflection-without -magic-smings jako sposób na bezpieczne uzyskanie informacji o nieruchomości. – walpen

Odpowiedz

4

Można zadzwonić MemberInfo.GetCustomAttributes() uzyskać wszelkie atrybuty niestandardowe zdefiniowane na członka a Type. Można uzyskać MemberInfo dla właściwości robiąc coś takiego:

PropertyInfo prop = typeof(Group).GetProperty("UserExistsInGroup", 
    BindingFlags.Public | BindingFlags.Static); 
+0

@Andy - przepraszam, powinienem był wyjaśnić, zobacz moją edycję. –

+0

Nie sądzę, że jest to możliwe, przynajmniej używając atrybutów takich, jakimi jesteś. Musisz uzyskać PropertyInfo dla właściwości, a jedynym sposobem, aby to zrobić, jest wyszukanie go za pomocą nazwy nieruchomości. – Andy

14

Wypróbuj następujące

var property = typeof(Group).GetProperty("UserExistsInGroup"); 
var attribute = property.GetCustomAttributes(typeof(DescriptionAttribute), true)[0]; 
var description = (DescriptionAttribute)attribute; 
var text = description.Description; 
+0

@JaredPar - przepraszam, powinienem był wyjaśnić, zobacz moją edycję. –

+0

Wiem, że jest dość stara odpowiedź, ale nie powinno być atrybutem "var description = (DescriptionAttribute);'? – Jack

2

Ok, widziałem tej edycji, nie jestem pewien, że można to zrobić za pomocą metod rozszerzających, jak byliby anaware z typ klasy zawierającej.

To zabrzmi trochę głupio, ale co powiesz na stworzenie nowej klasy "DescribedInt", która będzie miała domyślny operator cast, który pozwoli ci używać go jako int automatycznie? Będziesz w stanie w znacznym stopniu wykorzystać to, co opisujesz. Nadal będziesz mieć opis, ale kiedy trzeba używać go jak int, wont”trzeba uzyskać własności .DATA ...

np

private void ExampleUse() 
{ 
    int myvalue = Group.A; //see, no need to cast or say ".Data" - implicit cast 
    string text = Group.A.Description; 

// robić rzeczy z wartości ... }

public static class Group 
{ 
    public static DescribedInt A = new DescribedInt(12, "some description"); 
    public static DescribedInt B = new DescribedInt(88, "another description"); 
} 

public class DescribedInt 
{ 
    public readonly int data; 
    public readonly string Description; 

    public DescribedInt(int data, string description) 
    { 
     this.data = data; 
     this.Description = description; 
    } 

    //automatic cast to int 
    public static implicit operator int(DescribedInt orig) 
    { 
     return orig.data; 
    } 

    //public DescribedInt(string description) 
    //{ 
    // this.description = description; 
    //} 

    //if you ever need to go the "other way" 
    //public static implicit operator DescribedInt(int orig) 
    //{ 
    // return new DescribedInt(orig, ""); 
    //} 
} 
+0

@Ilaa - może to być opłacalna alternatywa. Przyjrzymy się bliżej jutro. Dzięki! –

2

Oto klasa pomocnika używam do przetwarzania niestandardowych atrybutów w .NET

public class AttributeList : List<Attribute> 
{ 
    /// <summary> 
    /// Gets a list of custom attributes 
    /// </summary> 
    /// <param name="propertyInfo"></param> 
    /// <returns></returns> 
    public static AttributeList GetCustomAttributeList(ICustomAttributeProvider propertyInfo) 
    { 
     var result = new AttributeList(); 
     result.AddRange(propertyInfo.GetCustomAttributes(false).Cast<Attribute>()); 
     return result; 
    } 

    /// <summary> 
    /// Finds attribute in collection by its type 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <returns></returns> 
    public T FindAttribute<T>() where T : Attribute 
    { 
     return (T)Find(x => typeof(T).IsAssignableFrom(x.GetType())); 
    } 

    public bool IsAttributeSet<T>() where T : Attribute 
    { 
     return FindAttribute<T>() != null; 
    } 
} 

Również testy jednostkowe dla MSTest pokazujące, jak korzystać z tej klasy

[TestClass] 
public class AttributeListTest 
{ 
    private class TestAttrAttribute : Attribute 
    { 
    } 

    [TestAttr] 
    private class TestClass 
    { 
    } 

    [TestMethod] 
    public void Test() 
    { 
     var attributeList = AttributeList.GetCustomAttributeList(typeof (TestClass)); 
     Assert.IsTrue(attributeList.IsAttributeSet<TestAttrAttribute>()); 
     Assert.IsFalse(attributeList.IsAttributeSet<TestClassAttribute>()); 
     Assert.IsInstanceOfType(attributeList.FindAttribute<TestAttrAttribute>(), typeof(TestAttrAttribute)); 
    } 
} 

http://www.kozlenko.info/2010/02/02/getting-a-list-of-custom-attributes-in-net/

+0

Mam go do pracy tutaj jest mój kod: var attributeList = AttributeList.GetCustomAttributeList (MethodInfo.GetCurrentMethod()); var attribute = attributeList.FindAttribute (). Opis; – Omzig

Powiązane problemy