2014-02-27 116 views
1

的所有屬性就拿下面的示例代碼:得到一個被覆蓋的屬性

public class TestMultipleAttributesAttribute : AttributeWithPriority 
    { 
     public string HelpMessage { get; set; } 
    } 

    public class Student 


    { 
     [TestMultipleAttributes(HelpMessage = "Student")] 
     public virtual string Name { get; set; } 

    } 

    public class SpecificStudent : Student 
    { 
     [TestMultipleAttributes(Priority = 100, HelpMessage = "SpecificStudent")] 
     public override string Name { get; set; } 
    } 

有什麼辦法通過反射我怎樣才能既TestMultipleAttributes的兩個實例對同一被覆蓋的財產?

我嘗試下面的代碼:該來的一點是找到property.DeclaringType

[Test] 
    public void testMultipleAttribs() 
    { 
     var property = typeof(SpecificStudent).GetProperties().FirstOrDefault(x => x.Name == "Name"); 

     var attribList = property.Attributes; //returns none 
     var customAttribs = property.CustomAttributes.ToList(); //returns 1 
     var customAttribs2 = property.GetCustomAttributes(inherit: true);// returns 1 
     int k = 5; 

    } 

一種解決方案,並重復該過程,並獲得屬性吧。然而,我不覺得它是一個很好的方法來做到這一點,並想知道是否有更好的方法。

+1

請,不包括有關在問題的標題,除非它是沒有意義的使用的語言信息沒有它。標籤用於此目的。 –

回答

0

您只有一個名爲TestMultipleAttributes的屬性並覆蓋了它。屬性具有多個屬性(PriorityHelpMessage)其正常工作。

您可以創建更多「真正」屬性,如StudentAttributeSpecificStudentAttribute

0

我不知道...這是相對優雅的(雖然我敢肯定我錯過了至少一個特例)。應該列舉所有的自定義在最近的優先順序上重寫或虛擬財產的屬性繼承鏈:

public static IEnumerable<Attribute> AllAttributes(PropertyInfo pi) 
{ 
    if (pi != null) 
    { 
    // enumerate all the attributes on this property 
    foreach (object o in pi.GetCustomAttributes(false)) 
    { 
     yield return (Attribute) o ; 
    } 

    PropertyInfo parentProperty = FindNearestAncestorProperty(pi) ; 
    foreach(Attribute attr in AllAttributesRecursive(parentProperty)) 
    { 
     yield return attr ; 
    } 

    } 

} 

private static PropertyInfo FindNearestAncestorProperty(PropertyInfo property) 
{ 
    if (property == null) throw new ArgumentNullException("property") ; 
    if (property.DeclaringType == null) throw new InvalidOperationException("all properties must belong to a type"); 

    // get the property's nearest "ancestor" property 
    const BindingFlags flags = BindingFlags.DeclaredOnly 
          | BindingFlags.Public | BindingFlags.NonPublic 
          | BindingFlags.Static | BindingFlags.Instance 
          ; 
    Type   t  = property.DeclaringType.BaseType ; 
    PropertyInfo ancestor = null ; 

    while (t != null && ancestor == null) 
    { 
    ancestor = t.GetProperty(property.Name,flags) ; 
    t  = t.BaseType ; 
    } ; 

    return ancestor ; 
}