2009-12-30 109 views
3

我有一個自定義屬性BacksCache,用於在滿足特定條件時需要「默認」的類中標記字段。獲取包含自定義屬性的所有字段

我用下面的代碼:

Type type = obj.GetType(); 
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy); 

foreach (FieldInfo field in fields) 
{ 
    foreach (Attribute at in field.GetCustomAttributes(true)) 
    if (at is BacksCache) 
    { 
    field.SetValue(obj, Utils.DefaultValue(field.FieldType)); 
    } 
} 

此代碼工作正常,只要該類繼承層次是平的。也就是說,如果type是聲明所有屬性字段的類型,那麼一切都很好。只要我有一個類A下降類BB : A)和B有一些歸屬領域的事情崩潰了:只有A宣佈的字段被檢測到和「違約」。

有問題的字段是privateprivate volatile,如果這有什麼區別。

有關如何解決此問題的任何想法?

回答

7

當心小字爲BindingFlags.FlattenHierarchy選項:

指定公共和保護 靜態成員組成層級應該 返回。 繼承類中的私有靜態成員 不是 返回。靜態成員包括 字段,方法,事件和 屬性。返回的嵌套類型不是 。

粗體短語中的「靜態」字是oops,不返回私有成員。要解決此問題,您需要通過Type.BaseType向上移動繼承鏈。

0

Attribute.GetCustomAttributes將搜索繼承值。代碼來執行,從而給你的例子是:

foreach (Attribute at in Attribute.GetCustomAttributes(field, true)) 
{ 
    // Test and set here 
} 

爲了進一步解釋見Weitao Su's post on GetCustomAttributes

2

你的措辭有點混亂,哪一類是基類A或B?你在反思哪個基類或派生類。我問,因爲我無法再現您的問題。我試過這個,它工作正常:

static void Main(string[] args) 
    { 

     foreach (var prop in typeof(Sub).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)) 
     { 
      foreach (var attrib in prop.GetCustomAttributes(typeof(DescriptionAttribute), false)) 
      { 
       Console.WriteLine(prop.Name); 
      } 
     } 

     Console.ReadKey(true); 
    } 


public class Base 
{ 
    [Description] 
    public int IntProp { get; set; } 
} 

public class Sub : Base 
{ 
    [Description] 
    public string StringProp { get; set; } 
} 

輸出是正確的,它顯示了兩個屬性。

此外,我只是注意到你正在處理字段。我這樣做,仍然得到正確的輸出:

static void Main(string[] args) 
    { 
     foreach (var prop in typeof(Sub).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)) 
     { 
      foreach (var attrib in prop.GetCustomAttributes(typeof(DescriptionAttribute), false)) 
      { 
       Console.WriteLine(prop.Name); 
      } 
     } 

     Console.ReadKey(true); 
    } 


public class Base 
{ 
    [Description] 
    public int X; 

    [Description] 
    public int IntProp { get; set; } 
} 

public class Sub : Base 
{ 
    [Description] 
    public int Y; 

    [Description] 
    public string StringProp { get; set; } 
} 

X和Y都輸出到控制檯。

+0

+1:對於含糊不清的問題抱歉,你的回答對於原問題的一種解釋是正確的。 – 2009-12-31 08:07:20

相關問題