tags:

views:

59

answers:

2

I am trying to reflect the fields in a derived type but it's returning the fields of the base type.

public class basetype
{
    string basevar;
}

public class derivedtype : basetype
{
    string derivedvar;
}

In some function:

derivedtype derived = new derivedtype();

FieldInfo[] fields = derived.GetType().GetFields();

This will return basevar, but not derivedvar. I've tried all the different bindings and it doesn't seem to make a difference.

Also, I'm doing this in ASP.NET within App_Code where basevar is defined in App_Code and derivedvar is a user control defined in App_Controls where the types are not in scope.

A: 

Reflection is a bit odd.

If the members are public, all of them up the entire hierarchy are visible.

If the members are non-public, you have to specify BindingFlags.NonPublic and you will only get those members that are of the type used. Inherited members are not visible. If you want to see all the non-public members of a type you'll have to walk up the inheritence chain.

Tergiver
This is not "odd", but exactly how it should be. Imagine you could give a field in a derived class any name, except the name of a private field in the base class. Then that private field wouldn't be that private anymore.
dtb
Correct me if I am wrong, but I think you are misunderstanding the issue here. My problem is with attempting to get the derived members, it is already returning the inherited members from the base class but not returning any of the members in the derived class. I tried BindingFlags.NonPublic but it didn't work either.
Epic720
@Epic720: as I mention above, I suspect that your class hierarchy is not as you describe (indeed it can't be - the two classes you show in your example aren't even related to each other!). Can you hack your real hierarchy down to something you can post?
Michael Petrotta
@dtb: You're right, it is as it should be. It's just not intuitive. If this is your first stab at reflection and you don't think it through, you may find it a bit odd.
Tergiver
+1  A: 

As is, this will return nothing as the default binding is for public fields only.

As is also, derivedtype isn't derived from basetype

With:

FieldInfo[] fields = derived.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

It returns derivedvar. I've just checked in LINQPad.

If I change derivedtype to be derived from basetype, then I can get both fields with:

FieldInfo[] fields = derived.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Concat(derived.GetType().BaseType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)).ToArray();
Jon Hanna
That was it, I was attempting to get the private members as well but I couldn't get it to work until I made the members private. Silly oversight on my part guys, sorry.
Epic720