private void ReflectGetProperties(Type classToReflect) {
Type currentType = classToReflect;
Hashtable propertyHash = null;
PropertyDescriptorCollection baseTypeProps = null;
// We only want to reflect on one level at a time,
// so if we have a base class above object, we get the
// properties for that first.
//
Type baseType = classToReflect.BaseType;
if (baseType != typeof(object) && baseType != null) {
baseTypeProps = DebugTypeDescriptor.GetProperties(baseType);
}
// for this particular type, we get _only_ the properties
// declared on that type
//
PropertyInfo[] props = classToReflect.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
// if we have properties from the base type, stick them into
// a hashtable because we'll want to override them with re-declared
// properties on this particular type.
//
if (baseTypeProps != null && baseTypeProps.Count > 0) {
propertyHash = new Hashtable();
foreach(PropertyDescriptor pd in baseTypeProps) {
propertyHash[pd.Name] = pd;
}
}
// now walk each property we got an make sure it's got a getter and a setter
//
foreach(PropertyInfo pi in props) {
if ((!(pi.DeclaringType.IsPublic || pi.DeclaringType.IsNestedPublic)) && (pi.DeclaringType.Assembly == typeof(DebugTypeDescriptor).Assembly)) {
continue;
}
bool addProp = true;
MethodInfo getMethod = pi.GetGetMethod();
MethodInfo setMethod = pi.GetSetMethod();
MethodInfo mi = getMethod;
// first just look to see if we have a getter
//
if (mi != null) {
// Ensure the get method has no parameters.
//
ParameterInfo[] parameters = mi.GetParameters();
if (parameters != null && parameters.Length != 0) {
addProp = false;
}
}
else {
addProp = false;
}
// build the property descriptor
// for this property.
//
if (addProp && mi != null && !mi.IsStatic && mi.IsPublic) {
// if we have a base list, push the new descriptor
// into the hashtable, otherwise just add it directly.
//
if (propertyHash != null) {
// okay, we have to get tricky here...
// if we got a property without a GetMethod, see if there's one in here we can use
//
if (getMethod == null) {
if (propertyHash.Contains(pi.Name)) {
// a base class has a property for this,
// so we should just pick up it's
// getter.
//
PropertyDescriptor basePd = (PropertyDescriptor)propertyHash[pi.Name];
Type declaringType = basePd.ComponentType;
if (declaringType != null) {
PropertyInfo baseProp = declaringType.GetProperty(pi.Name, pi.PropertyType);
if (baseProp != null) {
getMethod = baseProp.GetGetMethod();
}
else {
Debug.Fail("Base prop list has '" + pi.Name + "' but reflection didn't find it.");
}
}
}
}
// push the new info into the hash table.
//
propertyHash[pi.Name] = new DebugReflectPropertyDescriptor(classToReflect, pi.Name, pi.PropertyType, pi, getMethod, setMethod, null);;
}
else {
AddMember(new DebugReflectPropertyDescriptor(classToReflect, pi.Name, pi.PropertyType, pi, getMethod, setMethod, null));
}
}
}
// now all the things in the hashtable are our "actual" list
// of properties, so just set it directly.
//
if (propertyHash != null) {
this.memberHash = propertyHash;
}
}
}