代码之家  ›  专栏  ›  技术社区  ›  Kevin Montrose

获取具有自定义属性的所有字段(包括继承的字段)

  •  3
  • Kevin Montrose  · 技术社区  · 15 年前

    我有一个自定义属性 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 从中下课 B ( B : A ) 是否有一些属性字段的内容会分离:只有由声明的字段 检测到并“默认”。

    所讨论的字段是 private private volatile 如果有什么区别的话。

    有什么解决办法吗?

    3 回复  |  直到 14 年前
        1
  •  7
  •   Hans Passant    14 年前

    注意装订标记的小打印。平展Hierarchy选项:

    指定公共和受保护 层次结构上的静态成员应该 归还。 私有静态成员 在继承类中 返回 . 静态成员包括 字段、方法、事件和 性质。嵌套类型不是 返回。

    粗体短语中的“static”是一个oops,没有返回私有成员。要解决这个问题,您需要通过type.baseType向上移动继承链。

        2
  •  2
  •   BFree    15 年前

    您的措辞有点混乱,哪个类是基类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都将输出到控制台。

        3
  •  0
  •   Michael Greene    15 年前

    Attribute.GetCustomAttributes 将搜索继承的值。举个例子,这样做的代码是:

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

    有关进一步说明,请参阅 Weitao Su's post on GetCustomAttributes .