C# 使用自定义属性获取所有字段(包括继承的字段)

C# 使用自定义属性获取所有字段(包括继承的字段),c#,reflection,attributes,C#,Reflection,Attributes,我有一个自定义属性BacksCache,用于在满足某些条件时标记类中需要“默认”的字段 我正在使用以下代码: Type type = obj.GetType(); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy); foreach (FieldInfo field in

我有一个自定义属性
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
)和
B
有一些属性字段,事情就会分崩离析:只有
a
声明的字段被检测到并“默认”

有问题的字段是
private
private volatile
,如果有区别的话


有关如何修复此问题的任何想法?

属性。GetCustomAttributes
将搜索继承的值。在您的示例中,这样做的代码是:

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

有关进一步的解释,请参见。

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

注意BindingFlags.FlatterHierarchy选项的小字体:

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


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

+1:很抱歉有歧义,您的答案对于最初提出的问题的一种解释是正确的。为了澄清,这个答案不起作用,因为它没有获得私有字段。