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

PipelineMerge() private static method

Metadata merging is the second stage of our metadata pipeline. This stage merges extended metdata with primary metadata, and stores it in the cache if it is available.
private static PipelineMerge ( int pipelineType, ICollection primary, ICollection secondary, object instance, IDictionary cache ) : ICollection
pipelineType int
primary ICollection
secondary ICollection
instance object
cache IDictionary
return ICollection
        private static ICollection PipelineMerge(int pipelineType, ICollection primary, ICollection secondary, object instance, IDictionary cache)
        {
            // If there is no secondary collection, there is nothing to merge.
            //
            if (secondary == null || secondary.Count == 0)
            {
                return primary;
            }

            // Next, if we were given a cache, see if it has accurate data.
            //
            if (cache != null)
            {
                ICollection mergeCache = cache[s_pipelineMergeKeys[pipelineType]] as ICollection;
                if (mergeCache != null && mergeCache.Count == (primary.Count + secondary.Count))
                {
                    // Walk the merge cache.
                    IEnumerator mergeEnum = mergeCache.GetEnumerator();
                    IEnumerator primaryEnum = primary.GetEnumerator();
                    bool match = true;

                    while (primaryEnum.MoveNext() && mergeEnum.MoveNext())
                    {
                        if (primaryEnum.Current != mergeEnum.Current)
                        {
                            match = false;
                            break;
                        }
                    }

                    if (match)
                    {
                        IEnumerator secondaryEnum = secondary.GetEnumerator();

                        while (secondaryEnum.MoveNext() && mergeEnum.MoveNext())
                        {
                            if (secondaryEnum.Current != mergeEnum.Current)
                            {
                                match = false;
                                break;
                            }
                        }
                    }

                    if (match)
                    {
                        return mergeCache;
                    }
                }
            }

            // Our cache didn't match.  We need to merge metadata and return
            // the merged copy.  We create an array list here, rather than
            // an array, because we want successive sections of the 
            // pipeline to be able to modify it.
            //
            ArrayList list = new ArrayList(primary.Count + secondary.Count);
            foreach (object obj in primary)
            {
                list.Add(obj);
            }
            foreach (object obj in secondary)
            {
                list.Add(obj);
            }

            if (cache != null)
            {
                ICollection cacheValue;

                switch (pipelineType)
                {
                    case PIPELINE_ATTRIBUTES:
                        Attribute[] attrArray = new Attribute[list.Count];
                        list.CopyTo(attrArray, 0);
                        cacheValue = new AttributeCollection(attrArray);
                        break;

                    case PIPELINE_PROPERTIES:
                        PropertyDescriptor[] propArray = new PropertyDescriptor[list.Count];
                        list.CopyTo(propArray, 0);
                        cacheValue = new PropertyDescriptorCollection(propArray, true);
                        break;

                    case PIPELINE_EVENTS:
                        EventDescriptor[] eventArray = new EventDescriptor[list.Count];
                        list.CopyTo(eventArray, 0);
                        cacheValue = new EventDescriptorCollection(eventArray, true);
                        break;

                    default:
                        Debug.Fail("unknown pipeline type");
                        cacheValue = null;
                        break;
                }

                cache[s_pipelineMergeKeys[pipelineType]] = cacheValue;
                cache.Remove(s_pipelineFilterKeys[pipelineType]);
                cache.Remove(s_pipelineAttributeFilterKeys[pipelineType]);
            }

            return list;
        }