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

GetAttributes() private method

private GetAttributes ( object component, bool noCustomTypeDesc ) : AttributeCollection
component object
noCustomTypeDesc bool
return AttributeCollection
        public static AttributeCollection GetAttributes(object component, bool noCustomTypeDesc)
        {
            if (component == null)
            {
                Debug.Fail("COMPAT:  Returning an empty collection, but you should not pass null here");
                return new AttributeCollection((Attribute[])null);
            }

            // 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 = typeDesc.GetAttributes();

            // 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)
            {
                if (noCustomTypeDesc)
                {
                    ICustomTypeDescriptor extDesc = GetExtendedDescriptor(component);
                    if (extDesc != null)
                    {
                        ICollection extResults = extDesc.GetAttributes();
                        results = PipelineMerge(PIPELINE_ATTRIBUTES, results, extResults, component, null);
                    }
                }
                else
                {
                    results = PipelineFilter(PIPELINE_ATTRIBUTES, results, component, null);
                }
            }
            else
            {
                IDictionary cache = GetCache(component);

                results = PipelineInitialize(PIPELINE_ATTRIBUTES, results, cache);

                ICustomTypeDescriptor extDesc = GetExtendedDescriptor(component);
                if (extDesc != null)
                {
                    ICollection extResults = extDesc.GetAttributes();
                    results = PipelineMerge(PIPELINE_ATTRIBUTES, results, extResults, component, cache);
                }

                results = PipelineFilter(PIPELINE_ATTRIBUTES, results, component, cache);
            }

            AttributeCollection attrs = results as AttributeCollection;
            if (attrs == null)
            {
                Attribute[] attrArray = new Attribute[results.Count];
                results.CopyTo(attrArray, 0);
                attrs = new AttributeCollection(attrArray);
            }

            return attrs;
        }

Same methods

TypeDescriptor::GetAttributes ( Type componentType ) : AttributeCollection
TypeDescriptor::GetAttributes ( object component ) : AttributeCollection

Usage Example

Example #1
0
            /// <summary>
            /// Retrieves custom attributes.
            /// </summary>
            internal AttributeCollection GetAttributes()
            {
                // Worst case collision scenario:  we don't want the perf hit
                // of taking a lock, so if we collide we will query for
                // attributes twice. Not a big deal.
                if (_attributes == null)
                {
                    // Obtaining attributes follows a very critical order: we must take care that
                    // we merge attributes the right way. Consider this:
                    //
                    // [A4]
                    // interface IBase;
                    //
                    // [A3]
                    // interface IDerived;
                    //
                    // [A2]
                    // class Base : IBase;
                    //
                    // [A1]
                    // class Derived : Base, IDerived
                    //
                    // Calling GetAttributes on type Derived must merge attributes in the following
                    // order:  A1 - A4. Interfaces always lose to types, and interfaces and types
                    // must be merged in the same order. At the same time, we must be careful
                    // that we don't always go through reflection here, because someone could have
                    // created a custom provider for a type. Because there is only one instance
                    // of ReflectTypeDescriptionProvider created for typeof(object), if our code
                    // is invoked here we can be sure that there is no custom provider for
                    // _type all the way up the base class chain.
                    // We cannot be sure that there is no custom provider for
                    // interfaces that _type implements, however, because they are not derived
                    // from _type. So, for interfaces, we must go through TypeDescriptor
                    // again to get the interfaces attributes.

                    // Get the type's attributes. This does not recurse up the base class chain.
                    // We append base class attributes to this array so when walking we will
                    // walk from Length - 1 to zero.
                    //
                    Attribute[] attrArray = ReflectGetAttributes(_type);
                    Type        baseType  = _type.BaseType;

                    while (baseType != null && baseType != typeof(object))
                    {
                        Attribute[] baseArray = ReflectGetAttributes(baseType);
                        Attribute[] temp      = new Attribute[attrArray.Length + baseArray.Length];
                        Array.Copy(attrArray, temp, attrArray.Length);
                        Array.Copy(baseArray, 0, temp, attrArray.Length, baseArray.Length);
                        attrArray = temp;
                        baseType  = baseType.BaseType;
                    }

                    // Next, walk the type's interfaces. We append these to
                    // the attribute array as well.
                    int    ifaceStartIdx = attrArray.Length;
                    Type[] interfaces    = _type.GetInterfaces();
                    for (int idx = 0; idx < interfaces.Length; idx++)
                    {
                        Type iface = interfaces[idx];

                        // Only do this for public interfaces.
                        if ((iface.Attributes & (TypeAttributes.Public | TypeAttributes.NestedPublic)) != 0)
                        {
                            // No need to pass an instance into GetTypeDescriptor here because, if someone provided a custom
                            // provider based on object, it already would have hit.
                            AttributeCollection ifaceAttrs = TypeDescriptor.GetAttributes(iface);
                            if (ifaceAttrs.Count > 0)
                            {
                                Attribute[] temp = new Attribute[attrArray.Length + ifaceAttrs.Count];
                                Array.Copy(attrArray, temp, attrArray.Length);
                                ifaceAttrs.CopyTo(temp, attrArray.Length);
                                attrArray = temp;
                            }
                        }
                    }

                    // Finally, put all these attributes in a dictionary and filter out the duplicates.
                    OrderedDictionary attrDictionary = new OrderedDictionary(attrArray.Length);

                    for (int idx = 0; idx < attrArray.Length; idx++)
                    {
                        bool addAttr = true;
                        if (idx >= ifaceStartIdx)
                        {
                            for (int ifaceSkipIdx = 0; ifaceSkipIdx < s_skipInterfaceAttributeList.Length; ifaceSkipIdx++)
                            {
                                if (s_skipInterfaceAttributeList[ifaceSkipIdx].IsInstanceOfType(attrArray[idx]))
                                {
                                    addAttr = false;
                                    break;
                                }
                            }
                        }

                        if (addAttr && !attrDictionary.Contains(attrArray[idx].TypeId))
                        {
                            attrDictionary[attrArray[idx].TypeId] = attrArray[idx];
                        }
                    }

                    attrArray = new Attribute[attrDictionary.Count];
                    attrDictionary.Values.CopyTo(attrArray, 0);
                    _attributes = new AttributeCollection(attrArray);
                }

                return(_attributes);
            }
All Usage Examples Of System.ComponentModel.TypeDescriptor::GetAttributes