System.ComponentModel.DebugReflectPropertyDescriptor.FillAttributes C# (CSharp) Method

FillAttributes() protected method

protected FillAttributes ( IList attributes ) : void
attributes IList
return void
        protected override void FillAttributes(IList attributes) {
            Debug.Assert(componentClass != null, "Must have a component class for FillAttributes");

            //
            // The order that we fill in attributes is critical.  The list of attributes will be
            // filtered so that matching attributes at the end of the list replace earlier matches
            // (last one in wins).  Therefore, the three categories of attributes we add must be
            // added as follows:
            //
            // 1.  Attributes of the property type.  These are the lowest level and should be
            //     overwritten by any newer attributes.
            //
            // 2.  Attributes of the property itself, from base class to most derived.  This way
            //     derived class attributes replace base class attributes.
            //
            // 3.  Attributes from our base MemberDescriptor.  While this seems opposite of what
            //     we want, MemberDescriptor only has attributes if someone passed in a new
            //     set in the constructor.  Therefore, these attributes always
            //     supercede existing values.
            //
            
            
            // We need to include attributes from the type of the property.
            //
            foreach (Attribute typeAttr in DebugTypeDescriptor.GetAttributes(PropertyType)) {
                attributes.Add(typeAttr);
            }
        
            // NOTE : Must look at method OR property, to handle the case of Extender properties...
            //
            // Note : Because we are using BindingFlags.DeclaredOnly it is more effcient to re-aquire
            //      : the property info, rather than use the one we have cached.  The one we have cached
            //      : may ave come from a base class, meaning we will request custom metadata for this
            //      : class twice.

            BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly;
            Type currentReflectType = componentClass;
            int depth = 0;
            
            // First, calculate the depth of the object hierarchy.  We do this so we can do a single
            // object create for an array of attributes.
            //
            while(currentReflectType != null && currentReflectType != typeof(object)) {
                depth++;
                currentReflectType = currentReflectType.BaseType;
            }
            
            // Now build up an array in reverse order
            //
            if (depth > 0) {
                currentReflectType = componentClass;
                object[][] attributeStack = new object[depth][];
                
                while(currentReflectType != null && currentReflectType != typeof(object)) {
                
                    MemberInfo memberInfo = null;
                    
                    // Fill in our member info so we can get at the custom attributes.
                    //
                    if (IsExtender) {
                        memberInfo = currentReflectType.GetMethod("Get" + Name, bindingFlags);
                    }
                    else {
                        memberInfo = currentReflectType.GetProperty(Name, bindingFlags, null, PropertyType, new Type[0], new ParameterModifier[0]);
                    }
                    
                    // Get custom attributes for the member info.
                    //
                    if (memberInfo != null) {
                        attributeStack[--depth] = DebugTypeDescriptor.GetCustomAttributes(memberInfo);
                    }
                    
                    // Ready for the next loop iteration.
                    //
                    currentReflectType = currentReflectType.BaseType;
                }
                   
                // Now trawl the attribute stack so that we add attributes
                // from base class to most derived.
                //
                foreach(object[] attributeArray in attributeStack) {
                    if (attributeArray != null) {
                        foreach(object attr in attributeArray) {
                            if (attr is Attribute) {
                                attributes.Add(attr);
                            }
                        }
                    }
                }
            }
            
            // Include the base attributes.  These override all attributes on the actual
            // property, so we want to add them last.
            //
            base.FillAttributes(attributes);
            
            // Finally, override any form of ReadOnlyAttribute.  
            //
            if (!state[BitReadOnlyChecked]) {
                state[BitReadOnlyChecked] = true;
                if (SetMethodValue == null) {
                    attributes.Add(ReadOnlyAttribute.Yes);
                }
            }
        }