PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(
            Attribute[] attributes)
        {
            bool filtering = (attributes != null && attributes.Length > 0);
            PropertyDescriptorCollection props = _propCache;
            FilterCache cache = _filterCache;

            // Use a cached version if possible
            if (filtering && cache != null && cache.IsValid(attributes))
            {
                return(cache.FilteredProperties);
            }
            else if (!filtering && props != null)
            {
                return(props);
            }

            // Create the property collection and filter
            props = new PropertyDescriptorCollection(null);
            foreach (PropertyDescriptor prop in
                     TypeDescriptor.GetProperties(
                         _target, attributes, true))
            {
                props.Add(prop);
            }
            foreach (FieldInfo field in _target.GetType().GetFields())
            {
                FieldPropertyDescriptor fieldDesc =
                    new FieldPropertyDescriptor(field);
                if (!filtering ||
                    fieldDesc.Attributes.Contains(attributes))
                {
                    props.Add(fieldDesc);
                }
            }

            // Store the computed properties
            if (filtering)
            {
                cache                    = new FilterCache();
                cache.Attributes         = attributes;
                cache.FilteredProperties = props;
                _filterCache             = cache;
            }
            else
            {
                _propCache = props;
            }

            return(props);
        }
        public override bool Equals(object obj)
        {
            FieldPropertyDescriptor other = obj as FieldPropertyDescriptor;

            return(other != null && other._field.Equals(_field));
        }