GetFields of derived type - c#

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.

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();

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.

Related

How get private properties of Class/BaseClass?

I use this code:
BindingFlags flags= BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
PropertyInfo prop = myObj.GetProperty("Age", flags);
prop is not null. However, when I try to get all properties from myObj:
foreach(MemberInfo e in myObj.GetType().GetMembers( flags) ) { //neither GetProperties helps
Console.WriteLine(e.Name);
}
that property (Age) is not listed. I can't understand how this happens.
The dfiference between Type.GetProperty and Type.GetMembers is that both return private properties/members(which include properties), but GetMembers only of this type and not from base types whereas GetProperty also returns private properties of base types.
GetProperty:
Specify BindingFlags.NonPublic to include non-public properties (that
is, private, internal, and protected properties) in the search.
GetMembers:
Specify BindingFlags.NonPublic to include non-public members (that is,
private, internal, and protected members) in the search. Only
protected and internal members on base classes are returned; private
members on base classes are not returned.
So i guess that Age is an inherited property. If you would add BindingFlags.DeclaredOnly the result should be the same, you wouldn't see Age.
If you want to force GetMembers to include also private members of base types, use following extension method that loops all base types:
public static class TypeExtensions
{
public static MemberInfo[] GetMembersInclPrivateBase(this Type t, BindingFlags flags)
{
var memberList = new List<MemberInfo>();
memberList.AddRange(t.GetMembers(flags));
Type currentType = t;
while((currentType = currentType.BaseType) != null)
memberList.AddRange(currentType.GetMembers(flags));
return memberList.ToArray();
}
}
Now your BindingFlags work already and even a private "inherited" Age property is returned:
MemberInfo[] allMembers = myObj.GetType().GetMembersInclPrivateBase(flags);

Get protected property value of base class using reflection

I would like to know if it is possible to access the value of the ConfigurationId property which is located in the base class of the object and it's private. I have tried to do it with reflection with no luck.
To access ConfigurationId property i have used following code:
SubsetController controller = new SubsetController(new CConfigRepository(new FakeDataContextRepository()));
var myBaseClassProtectedProperty =
controller.GetType().BaseType
.GetProperty("CCITenderInfo", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(controller);
var myProtectedProperty =
CCITenderInfo.GetType()
.GetProperty("ConfigurationId", BindingFlags.Public | BindingFlags.Instance)
.GetValue(myBaseClassProtectedProperty);
Assuming the following parent and child class:
class BaseClass
{
private string privateField = "I'm Private";
}
class ChildClass : BaseClass
{
}
You can read privateField's value from a ChildClass instance using reflection like this:
ChildClass childInstance = new ChildClass();
object privateFieldValue = childInstance.GetType().BaseType
.GetField("privateField", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(childInstance);
Console.WriteLine(privateFieldValue); // I'm Private
To add to this answer - you should use the Instance and NonPublic binding flags for sure, but you should also ensure that you are actually referencing properties and not fields.
E.g. if you have
protected string Andrew;
You will not be able to get this via GetProperty, no matter what binding flags you use. Why - because it is a field, and not a property...
To fix this, just change it to
protected string Andrew {get;set;}
and then you can use the GetProperty method.
Yes, this is possible with reflection.
However, in order to look up nonpublic members, you'll need to use the reflection overload which take BindingFlags parameters. In order to look up private members, you'll also need to access via the typeof the base class, even when using BindingFlags.FlattenHierarchy. This also means you'll need to use the exact binding, however note that contradictory flags (such as using both NonPublic and Public) are valid and will return either at that point.
Be aware that the very need to look up nonpublic members could be considered code smell, and you should do so very carefully. Also be aware that nonpublic members are not guaranteed to have the same names across different versions.

Check if a "Type" override a dynamic type

We are giving some repetitive jobs to a consultant company, we just have a few constraints that could not be checked by compilation, like a requirement to override a specific property in all class implementing a specific interface.
The property of the interface, which should be overrided in all classes has the following signature:
dynamic Definition{get;}
I found this stackoverflow question: How to find out if property is inherited from a base class or declared in derived?
Which is closed to my case, but in my case, the property is defined is inherited class and overrided in this one:
public class ClassA:IMyInterface
{
public virtual dynamic Definition{get{ /*return SomethingSpecificToClassA;*/}}
}
public class ClassB:ClassA
{
public override dynamic Definition{get{ /*return SomethingSpecificToClassB;*/}}
}
//The end goal is to know if ClassB has correctly overriden the property
bool overriden = typeof(ClassB)GetProperties(...).Any(p=>p.Name=="Definition");
This is the solution: you ask ClassB its interface map, you look for the method you want in the interface map and then you look where the implementation method (classMethod) is declared.
var interfaceMethod = typeof(I).GetProperty("Definition").GetGetMethod();
var map = typeof(ClassB).GetInterfaceMap(typeof(I));
var ix = Array.IndexOf(map.InterfaceMethods, interfaceMethod);
var classMethod = map.TargetMethods[ix];
bool isDeclaredInClass = classMethod.DeclaringType == typeof(ClassB);
You can find for property declared only in your type of interests:
var prop = typeof (ClassB).GetProperty("Definition", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
Then you can then check if its getter is virtual:
prop.GetMethod.IsVirtual
which will be false if Definition hides (or uses new) in ClassB

Get all properties of current class and base class

I have 2 classes (lets say "BaseItem" and "ChildItem") with several internal properties. In the BaseClass i have defined a method which should read out all of this properties with
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(this);
or
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(this.GetType());
When i call this method in an instance of "ChildItem", i get only the properties that are defined in "ChildItem". What can i do to get also the the properties of "BaseItem"?
Regards
Dave
For internal properties (as clarified in the question comments), although not indicated (they're internal for a reason), you can use:
var internalProperties = GetType().GetProperties(
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public));
It's the flag BindingFlags.NonPublic that needs to be applied.
You could just cast it to BaseItem and do GetProperties() separately..

in C#, Is there anyway to determine a class's members at runtime?

Suppose I have a class named foo, and it has 3 public members foo1, foo2, and foo3.
Now suppose I'm writing a function that takes an instance of class foo as a parameter, but when I'm writing this function I have no idea what public members it has.
Is there a way for me to determine at run-time that it has public members foo1, foo2, foo3 AND ONLY foo1, foo2, foo3. IE - find out what all the public members are?
And can I also determine their types?
Well, that's what Reflection is there for :
Type myObjectType = typeof(foo);
System.Reflection.FieldInfo[] fieldInfo = myObjectType.GetFields();
foreach (System.Reflection.FieldInfo info in fieldInfo)
Console.WriteLine(info.Name); // or whatever you desire to do with it
You could use reflection:
// List all public properties for the given type
PropertyInfo[] properties = foo.GetType().GetProperties();
foreach (var property in properties)
{
string propertyName = property.Name;
}
You should be aware that there could be an additional overhead when using reflection because types are evaluated at runtime.
Have a look at the .net reflection namespace:
http://msdn.microsoft.com/en-us/library/ms173183(VS.80).aspx
This is a job for reflection. Look into methods like:
myFoo.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public);
This will return all public, instance methods that the type has. You can then look through the returned results and determine if this class meets your criteria. There are equivalent methods as well for other types of members, such as GetFields(...), GetProperties(...), etc.
Basically you want to get to know the Type class, which is the core of C#'s reflection capabilities.
foreach(PropertyInfo pi in yourObject.GetType().GetProperties())
{
Type theType = pi.PropertyType;
}
Following article on MSDN should help you determine the methods of a type

Categories