System.ComponentModel.TypeDescriptor.GetPropertiesImpl C# (CSharp) Method

GetPropertiesImpl() private static method

Gets a collection of properties for a specified component. Uses the attribute filter only if noAttributes is false. This is to preserve backward compat for the case when no attribute filter was passed in (as against passing in null).
private static GetPropertiesImpl ( object component, Attribute attributes, bool noCustomTypeDesc, bool noAttributes ) : PropertyDescriptorCollection
component object
attributes System.Attribute
noCustomTypeDesc bool
noAttributes bool
return PropertyDescriptorCollection
        private static PropertyDescriptorCollection GetPropertiesImpl(object component, Attribute[] attributes, bool noCustomTypeDesc, bool noAttributes)
        {
            if (component == null)
            {
                Debug.Fail("COMPAT:  Returning an empty collection, but you should not pass null here");
                return new PropertyDescriptorCollection(null, true);
            }

            // We create a sort of pipeline for mucking with metadata.  The pipeline
            // goes through the following process:
            //
            // 1.  Merge metadata from extenders.
            // 2.  Allow services to filter the metadata
            // 3.  If an attribute filter was specified, apply that.
            // 
            // The goal here is speed.  We get speed by not copying or
            // allocating memory.  We do this by allowing each phase of the
            // pipeline to cache its data in the object cache.  If
            // a phase makes a change to the results, this change must cause
            // successive phases to recompute their results as well.  "Results" is
            // always a collection, and the various stages of the pipeline may
            // replace or modify this collection (depending on if it's a
            // read-only IList or not).  It is possible for the orignal
            // descriptor or attribute collection to pass through the entire
            // pipeline without modification.
            // 
            ICustomTypeDescriptor typeDesc = GetDescriptor(component, noCustomTypeDesc);
            ICollection results;

            // If we are handed a custom type descriptor we have several choices of action
            // we can take.  If noCustomTypeDesc is true, it means that the custom type
            // descriptor is trying to find a baseline set of properties.  In this case
            // we should merge in extended properties, but we do not let designers filter
            // because we're not done with the property set yet.  If noCustomTypeDesc
            // is false, we don't do extender properties because the custom type descriptor
            // has already added them.  In this case, we are doing a final pass so we
            // want to apply filtering.  Finally, if the incoming object is not a custom
            // type descriptor, we do extenders and the filter.
            //
            if (component is ICustomTypeDescriptor)
            {
                results = noAttributes ? typeDesc.GetProperties() : typeDesc.GetProperties(attributes);
                if (noCustomTypeDesc)
                {
                    ICustomTypeDescriptor extDesc = GetExtendedDescriptor(component);
                    if (extDesc != null)
                    {
                        ICollection extResults = noAttributes ? extDesc.GetProperties() : extDesc.GetProperties(attributes);
                        results = PipelineMerge(PIPELINE_PROPERTIES, results, extResults, component, null);
                    }
                }
                else
                {
                    results = PipelineFilter(PIPELINE_PROPERTIES, results, component, null);
                    results = PipelineAttributeFilter(PIPELINE_PROPERTIES, results, attributes, component, null);
                }
            }
            else
            {
                IDictionary cache = GetCache(component);
                results = noAttributes ? typeDesc.GetProperties() : typeDesc.GetProperties(attributes);
                results = PipelineInitialize(PIPELINE_PROPERTIES, results, cache);
                ICustomTypeDescriptor extDesc = GetExtendedDescriptor(component);
                if (extDesc != null)
                {
                    ICollection extResults = noAttributes ? extDesc.GetProperties() : extDesc.GetProperties(attributes);
                    results = PipelineMerge(PIPELINE_PROPERTIES, results, extResults, component, cache);
                }

                results = PipelineFilter(PIPELINE_PROPERTIES, results, component, cache);
                results = PipelineAttributeFilter(PIPELINE_PROPERTIES, results, attributes, component, cache);
            }

            PropertyDescriptorCollection props = results as PropertyDescriptorCollection;
            if (props == null)
            {
                PropertyDescriptor[] propArray = new PropertyDescriptor[results.Count];
                results.CopyTo(propArray, 0);
                props = new PropertyDescriptorCollection(propArray, true);
            }

            return props;
        }