Search code examples
c#reflectionbindingflags

Not getting fields from GetType().GetFields with BindingFlag.Default


I am using the Reflection classes in order to get all the fields inside a certain object. My problem however is that it works perfectly when the fields are inside a normal class, like:

class test
{
   string test1 = string.Empty;
   string test2 = string.Empty;
}

Here i get both test1 and test2, my problem is that i use abstraction and thus several classes combined.

I got something like:

class test3 : test2
{
   string test4 = string.Empty;
   string test5 = string.Empty;
}

class test2 : test1
{
   string test2 = string.Empty;
   string test3 = string.Empty;
}
class test1
{
   string test0 = string.Empty;
   string test1 = string.Empty;
}

But when I run it, I don't get the fields back from the GetType().GetFields(BindingFlag.Default).

Everyone of those fields also have a property, get; set; attached to it. When I run the code, I get the properties all the way back to test1 but not the actual fields.

This is the code that I'm trying to get the fields with:

FieldInfo[] fields = Obj.GetType().GetFields(BindingFlags.Default);
foreach (FieldInfo field in fields)

I have also tried:

FieldInfo[] fields = Obj.GetType().GetFields(BindingFlags.Public 
                                             | BindingFlags.Instance 
                                             | BindingFlags.NonPublic 
                                             | BindingFlags.Static);

I use the same code for the properties:

PropertyInfo[] properties = Obj.GetType().GetProperties(BindingFlags.Public 
                                             | BindingFlags.Instance 
                                             | BindingFlags.NonPublic 
                                             | BindingFlags.Static);

foreach (PropertyInfo property in properties)

Any ideas why I get the properties from the abstracted classes but not the fields?


Solution

  • Edit: To get private members of the base type, you have to:

    typeof(T).BaseType.GetFields(...)
    

    Edit again: Win.

    Edit 3/22/13: Used Concat instead of Union. Since we are specifying BindingFlags.DeclaredOnly and a type's BaseType cannot equal itself, Union is not needed and is more expensive.

    public static IEnumerable<FieldInfo> GetAllFields(Type t)
    {
        if (t == null)
            return Enumerable.Empty<FieldInfo>();
    
        BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | 
                             BindingFlags.Static | BindingFlags.Instance | 
                             BindingFlags.DeclaredOnly;
        return t.GetFields(flags).Concat(GetAllFields(t.BaseType));
    }