public void NeedsFilterCheck_only_returns_ids_not_already_cached() { var cache = new FilterCache(); cache.NeedsFilterCheck(new ulong?[] { 1, 3, 5 }); Assert.AreEqual(new ulong[] { 2, 4, 6 }, cache.NeedsFilterCheck(new ulong?[] { 1, 2, 3, 4, 5, 6 }).ToArray()); }
public void IsFiltered_for_id_seen_by_NeedsFilterCheck_but_not_marked_by_MarkAsFiltered_returns_false() { var cache = new FilterCache(); cache.NeedsFilterCheck(new ulong?[] { 123 }); Assert.IsFalse(cache.IsFiltered(123)); }
public void NeedsFilterCheck_marks_all_canidates_as_not_filtered() { var cache = new FilterCache(); cache.NeedsFilterCheck(new ulong?[] { 1, 2, 3 }); Assert.AreEqual(new[] { "1f", "2f", "3f" }, cache.Select(x => x.Key + (x.Value ? "t" : "f")).ToArray()); }
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) { bool filtering = (null != attributes && 0 < attributes.Length); PropertyDescriptorCollection props = InitializePropertyDescriptors(); if (props == null) { return(props); } 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); } //Build up the attribute cache, since our PropertyDescriptor doesn't store it internally. // _values is set only during construction. if (null == _attrCache && null != attributes && 0 < attributes.Length) { _attrCache = new Dictionary <object, AttributeCollection>(); foreach (FieldDescriptor pd in _propertyDescriptors) { object o = pd.GetValue(this); object[] atts = o.GetType().GetCustomAttributes(/*inherit*/ false); //atts will not be null (atts.Length==0) Attribute[] attrArray = new Attribute[atts.Length]; atts.CopyTo(attrArray, 0); _attrCache.Add(pd, new AttributeCollection(attrArray)); } } //Create the filter based on the attributes. props = new PropertyDescriptorCollection(null); foreach (PropertyDescriptor pd in _propertyDescriptors) { if (_attrCache[pd].Matches(attributes)) { props.Add(pd); } } // Store the computed properties if (filtering) { cache = new FilterCache(); cache.Attributes = attributes; cache.FilteredProperties = props; _filterCache = cache; } return(props); }
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) { bool filtering = (attributes != null && attributes.Length > 0); PropertyDescriptorCollection props = _propCache; FilterCache cache = _filterCache; // Use a cached version if we can if (filtering && cache != null && cache.IsValid(attributes)) { return(cache.FilteredProperties); } if (!filtering && props != null) { return(props); } // загрузка доступных ресурсов var manifests = GetType().Assembly.GetManifestResourceNames(); var manager = manifests.Select(m => m.Replace(".resources", string.Empty)) .Select(manifest => new ResourceManager(manifest, GetType().Assembly)) .ToList(); // Create the property collection and filter if necessary props = new PropertyDescriptorCollection(null); foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(this, attributes, true)) { var attr = prop.Attributes.Cast <Attribute>().ToArray(); // проверка атрибута локализации var lo = prop.Attributes[typeof(LocalizableAttribute)]; if (lo != null && ((LocalizableAttribute)lo).IsLocalizable) { // создание локализуемой версии свойства props.Add(new LocalizePropertDescription(prop, attr, manager)); } else { // копирование свойства без изменений props.Add(prop); } } // Store the computed properties if (filtering) { cache = new FilterCache { Attributes = attributes, FilteredProperties = props }; _filterCache = cache; } else { _propCache = props; } return(props); }
public void IsFiltered_for_id_marked_by_MarkAsFiltered_returns_true() { var cache = new FilterCache(); cache.NeedsFilterCheck(new ulong?[] { 123 }); cache.MarkAsFiltered(new ulong[] { 123 }); Assert.IsTrue(cache.IsFiltered(123)); }
public void MarkAsFiltered_marks_all_provided_ids_as_filtered() { var cache = new FilterCache(); cache.NeedsFilterCheck(new ulong?[] { 1, 2, 3, 4, 5, 6 }); cache.MarkAsFiltered(new ulong[] { 5, 3, 1 }); Assert.AreEqual(new[] { "1t", "2f", "3t", "4f", "5t", "6f" }, cache.Select(x => x.Key + (x.Value ? "t" : "f")).ToArray()); }
/// <summary> /// /// </summary> /// <param name="attributes"></param> /// <returns></returns> public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { // Retrieve cached properties and filtered properties var filtering = attributes != null && attributes.Length > 0; var cache = provider.filterCache; var props = provider.propCache; // Use a cached version if we can if (filtering && cache != null && cache.IsValid(attributes)) { return(cache.FilteredProperties); } if (!filtering && props != null) { return(props); } var properties1 = new Dictionary <string, PropertyDescriptor>(); { foreach (PropertyDescriptor prop in base.GetProperties()) { properties1[prop.Name] = prop; } } if (objectType.IsInterface) { foreach (var interfaceType in objectType.GetInterfaces()) { foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(interfaceType)) { properties1[prop.Name] = prop; } } } var properties = new ArrayList(properties1.Values); //Store the updated properties props = new PropertyDescriptorCollection( (PropertyDescriptor[])properties.ToArray(typeof(PropertyDescriptor)), false); if (filtering) { cache = new FilterCache { FilteredProperties = props, Attributes = attributes }; provider.filterCache = cache; } else { provider.propCache = props; } return(props); }
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { // Retrieve cached properties and filtered properties bool filtering = attributes is { Length : > 0 }; FilterCache cache = _provider._filterCache; PropertyDescriptorCollection properties = _provider._propCache; // Use a cached version if we can if (filtering && cache != null && cache.IsValid(attributes)) { return(cache.FilteredProperties); } if (!filtering && properties != null) { return(properties); } // Otherwise, create the property collection properties = new PropertyDescriptorCollection(null); foreach (PropertyInfo property in _objectType.GetProperties()) { // FieldInfo[] pflds = p.PropertyType.GetFields(); PropertyInfo[] propertyInfos = property.PropertyType.GetProperties(); // if the property in not an array and has public fields or properties - use ExpandablePropertyDescriptor PropertyDescriptor desc = !property.PropertyType.HasElementType && propertyInfos.Length > 0 ? new ExpandablePropertyDescriptor(property) : new DefaultPropertyDescriptor(property); if (!filtering || desc.Attributes.Contains(attributes)) { properties.Add(desc); } } // Store the updated properties if (filtering) { cache = new FilterCache { FilteredProperties = properties, Attributes = attributes }; _provider._filterCache = cache; } else { _provider._propCache = properties; } // Return the computed properties return(properties); } }
protected override RESULT Initial(StringBuilder messager) { LastDayEntities = new Dictionary <string, DBTStkDailyEntity>(); CurrentEntities = new Dictionary <string, TengxunStockInfoEntity>(); service = new TengxunDataService(); tables = new List <string>(); filter4idx = new FilterCache <ItemInfoEntity>(1000); filter4stk = new FilterCache <ItemInfoEntity>(1000); lines = new Dictionary <string, TengxunMinuteLine>(); return(base.Initial(messager)); }
static FilterFactory() { FilterCache filter_cache = new FilterCache (filter_cache_dir); ReflectionFu.ScanEnvironmentForAssemblies ("BEAGREP_FILTER_PATH", PathFinder.FilterDir, delegate (Assembly a) { int n = ScanAssemblyForFilters (a, filter_cache); Logger.Log.Debug ("Loaded {0} filter{1} from {2}", n, n == 1 ? "" : "s", a.Location); }); // FIXME: Up external filter version if external-filters.xml is modified // Check if cache is dirty and also update the cache on the disk cache_dirty = filter_cache.UpdateCache (); }
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { // Retrieve cached properties and filtered properties bool filtering = attributes != null && attributes.Length > 0; FilterCache cache = _provider._filterCache; PropertyDescriptorCollection props = _provider._propCache; // Use a cached version if we can if (filtering && cache != null && cache.IsValid(attributes)) { return(cache.FilteredProperties); } else if (!filtering && props != null) { return(props); } // Otherwise, create the property collection props = new PropertyDescriptorCollection(null); foreach (PropertyDescriptor prop in base.GetProperties(attributes)) { props.Add(prop); } foreach (FieldInfo field in _objectType.GetFields()) { FieldPropertyDescriptor fieldDesc = new FieldPropertyDescriptor(field); if (!filtering || fieldDesc.Attributes.Contains(attributes)) { props.Add(fieldDesc); } } // Store the updated properties if (filtering) { cache = new FilterCache(); cache.FilteredProperties = props; cache.Attributes = attributes; _provider._filterCache = cache; } else { _provider._propCache = props; } // Return the computed properties return(props); }
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) { bool filtering = (attributes != null && attributes.Length > 0); PropertyDescriptorCollection props = cachedPropertyDescriptors; FilterCache cache = cachedFilter; // 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( this, attributes, true)) { props.Add(prop); } foreach (FieldInfo field in this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance)) { 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; cachedFilter = cache; } else { cachedPropertyDescriptors = props; } return(props); }
/// <summary> /// Expert: by default, the cached filter will be shared /// across reopened segments that only had changes to their /// deletions. /// </summary> /// <param name="filter">Filter to cache results of</param> /// <param name="deletesMode">See <see cref="DeletesMode" /></param> /// public CachingWrapperFilter(Filter filter, DeletesMode deletesMode) { this.filter = filter; cache = new AnonymousFilterCache(deletesMode); //cache = new FilterCache(deletesMode) // { // public Object mergeDeletes(final IndexReader r, final Object docIdSet) { // return new FilteredDocIdSet((DocIdSet) docIdSet) { // protected boolean match(int docID) { // return !r.isDeleted(docID); // } // }; // } //}; }
/** * Expert: by default, the cached filter will be shared * across reopened segments that only had changes to their * deletions. * * @param filter Filter to cache results of * @param deletesMode See {@link DeletesMode} */ public CachingWrapperFilter(Filter filter, DeletesMode deletesMode) { this.filter = filter; cache = new AnonymousFilterCache(deletesMode); //cache = new FilterCache(deletesMode) // { // public Object mergeDeletes(final IndexReader r, final Object docIdSet) { // return new FilteredDocIdSet((DocIdSet) docIdSet) { // protected boolean match(int docID) { // return !r.isDeleted(docID); // } // }; // } //}; }
static FilterFactory() { FilterCache filter_cache = new FilterCache(filter_cache_dir); ReflectionFu.ScanEnvironmentForAssemblies("BEAGREP_FILTER_PATH", PathFinder.FilterDir, delegate(Assembly a) { int n = ScanAssemblyForFilters(a, filter_cache); Logger.Log.Debug("Loaded {0} filter{1} from {2}", n, n == 1 ? "" : "s", a.Location); }); // FIXME: Up external filter version if external-filters.xml is modified // Check if cache is dirty and also update the cache on the disk cache_dirty = filter_cache.UpdateCache(); }
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) { bool filtering = (attributes != null && attributes.Length > 0); PropertyDescriptorCollection props = _propCache; FilterCache cache = _filterCache; // Use a cached version if we can if (filtering && cache != null && cache.IsValid(attributes)) { return(cache.FilteredProperties); } else if (!filtering && props != null) { return(props); } // Create the property collection and filter if necessary props = new PropertyDescriptorCollection(null); foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(_target, attributes, true)) { string displayNameLng = LanguageHelper.Instance.ReadKeyValueFromResources(formName, prop.Name); string categoryLng = LanguageHelper.Instance.ReadKeyValueFromResources(formName, prop.Category); props.Add(new LngPropertyDescriptor(prop, displayNameLng, "", categoryLng)); } // Store the computed properties if (filtering) { cache = new FilterCache(); cache.Attributes = attributes; cache.FilteredProperties = props; _filterCache = cache; } else { _propCache = props; } return(props); }
/** * Expert: by default, the cached filter will be shared * across reopened segments that only had changes to their * deletions. * * @param filter Filter to cache results of * @param deletesMode See {@link DeletesMode} */ public CachingWrapperFilter(Filter filter, DeletesMode deletesMode) { this.filter = filter; cache = new FilterCache <DocIdSet>(deletesMode, (reader, docIdSet) => { return(new FilteredDocIdSet((DocIdSet)docIdSet, (docid) => { return !reader.IsDeleted(docid); })); }); //cache = new FilterCache(deletesMode) // { // public Object mergeDeletes(final IndexReader r, final Object docIdSet) { // return new FilteredDocIdSet((DocIdSet) docIdSet) { // protected boolean match(int docID) { // return !r.isDeleted(docID); // } // }; // } //}; }
static private int ScanAssemblyForFilters(Assembly assembly, FilterCache filter_cache) { int count = 0; foreach (Type t in ReflectionFu.GetTypesFromAssemblyAttribute(assembly, typeof(FilterTypesAttribute))) { Filter filter = null; try { filter = (Filter)Activator.CreateInstance(t); } catch (Exception ex) { Logger.Log.Error(ex, "Caught exception while instantiating {0}", t); } if (filter == null) { continue; } filter_versions_by_name [t.ToString()] = filter.Version; foreach (FilterFlavor flavor in filter.SupportedFlavors) { FilterFlavor.FilterTable [flavor] = t; } ++count; } if (count > 0) { DateTime last_mtime = File.GetLastWriteTimeUtc(assembly.Location); filter_cache.RegisterFilter(assembly.Location, last_mtime); } return(count); }
private Regex GetFilter(String filter, Boolean matchWholeWord = false) { if (filter == null) { filter = String.Empty; } if (filter.Any(character => InvalidFilterCharacters.Contains(character))) { throw new ArgumentException("filter contains invalid characters"); } if (filter.Contains('/')) { filter = filter.Replace('/', '\\'); } var result = default(Regex); lock (FilterCache) { filter = Regex.Escape(filter).Replace("\\*", ".*").Replace("\\?", "."); if (matchWholeWord) { filter = "^" + filter + "$"; } if (!FilterCache.TryGetValue(filter, out result)) { FilterCache[filter] = result = new Regex(filter, RegexOptions.Compiled | RegexOptions.IgnoreCase); } } return(result); }
public void IsFiltered_for_null_id_returns_false() { var cache = new FilterCache(); Assert.IsFalse(cache.IsFiltered(null)); }
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) { bool filtering = (attributes != null && attributes.Length > 0); PropertyDescriptorCollection props = _propCache; FilterCache cache = _filterCache; // Use a cached version if we can if (filtering && cache != null && cache.IsValid(attributes)) { return cache.FilteredProperties; } else if (!filtering && props != null) { return props; } // Create the property collection and filter if necessary props = new PropertyDescriptorCollection(null); foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(_target, attributes, true)) { if (prop.IsReadOnly == false) props.Add(prop); } foreach (FieldInfo field in _target.GetType().GetFields(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance)) { 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 void NeedsFilterCheck_discards_null_ids() { var cache = new FilterCache(); Assert.AreEqual(new ulong[] { 1, 2, 3 }, cache.NeedsFilterCheck(new ulong?[] { 1, null, 2, null, 3 }).ToArray()); }
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { // Retrieve cached properties and filtered properties bool filtering = attributes != null && attributes.Length > 0; FilterCache cache = _provider._filterCache; PropertyDescriptorCollection props = _provider._propCache; // Use a cached version if we can if (filtering && cache != null && cache.IsValid(attributes)) return cache.FilteredProperties; else if (!filtering && props != null) return props; // Otherwise, create the property collection props = new PropertyDescriptorCollection(null); /*foreach (PropertyDescriptor prop in base.GetProperties(attributes)) { props.Add(prop); }*/ foreach (FieldInfo field in _objectType.GetFields(BindingFlags.Public | BindingFlags.Instance)) { FieldPropertyDescriptor fieldDesc = new FieldPropertyDescriptor(field); if (!filtering || fieldDesc.Attributes.Contains(attributes)) props.Add(fieldDesc); } // Store the updated properties if (filtering) { cache = new FilterCache(); cache.FilteredProperties = props; cache.Attributes = attributes; _provider._filterCache = cache; } else _provider._propCache = props; // Return the computed properties return props; }
public void IsFiltered_for_id_marked_by_MarkAsFiltered_returns_true() { var cache = new FilterCache(); cache.NeedsFilterCheck(new ulong?[] { 123 }); cache.MarkAsFiltered(new ulong[]{123}); Assert.IsTrue(cache.IsFiltered(123)); }
public void NeedsFilterCheck_distincts_output() { var cache = new FilterCache(); Assert.AreEqual(new ulong[] { 1, 2, 3 }, cache.NeedsFilterCheck(new ulong?[] { 1, 2, 1, 3, 2, 1 }).ToArray()); }
public void IsFiltered_for_id_seen_by_NeedsFilterCheck_but_not_marked_by_MarkAsFiltered_returns_false() { var cache = new FilterCache(); cache.NeedsFilterCheck(new ulong?[] {123}); Assert.IsFalse(cache.IsFiltered(123)); }
public void IsFiltered_for_unknown_id_returns_false() { var cache = new FilterCache(); Assert.IsFalse(cache.IsFiltered(123)); }
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(this, attributes, true)) { props.Add(prop); } foreach (FieldInfo field in 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; }
static private int ScanAssemblyForFilters (Assembly assembly, FilterCache filter_cache) { int count = 0; foreach (Type t in ReflectionFu.GetTypesFromAssemblyAttribute (assembly, typeof (FilterTypesAttribute))) { Filter filter = null; try { filter = (Filter) Activator.CreateInstance (t); } catch (Exception ex) { Logger.Log.Error (ex, "Caught exception while instantiating {0}", t); } if (filter == null) continue; filter_versions_by_name [t.ToString ()] = filter.Version; foreach (FilterFlavor flavor in filter.SupportedFlavors) FilterFlavor.FilterTable [flavor] = t; ++count; } if (count > 0) { DateTime last_mtime = File.GetLastWriteTimeUtc (assembly.Location); filter_cache.RegisterFilter (assembly.Location, last_mtime); } return count; }
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { // Retrieve cached properties and filtered properties var filtering = attributes != null && attributes.Length > 0; var cache = _provider._filterCache; var props = _provider._propCache; // Use a cached version if we can if (filtering && cache != null && cache.IsValid(attributes)) { return(cache.FilteredProperties); } if (!filtering && props != null) { return(props); } // use a stack to reverse hierarchy // if fieldnames occure in more than one class // use the one from the class that is highest in the class hierarchy var objectHierarchy = new Stack <Type>(); var curType = _objectType; while (curType != null) { objectHierarchy.Push(curType); curType = curType.BaseType; } // Otherwise, create the property collection props = new PropertyDescriptorCollection(null); foreach (PropertyDescriptor prop in base.GetProperties(attributes)) { props.Add(prop); } // list to rememnber already added names var addedMemberNames = new List <string>(); while (objectHierarchy.Count > 0) { curType = objectHierarchy.Pop(); AddTypeFields(curType, attributes, props, addedMemberNames); AddTypeProperties(curType, attributes, props); } // Store the updated properties if (filtering) { cache = new FilterCache { FilteredProperties = props, Attributes = attributes }; _provider._filterCache = cache; } else { _provider._propCache = props; } // Return the computed properties return(props); }
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) { var filtering = (null != attributes && 0 < attributes.Length); var props = InitializePropertyDescriptors(); if (props == null) { return props; } var 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; } //Build up the attribute cache, since our PropertyDescriptor doesn't store it internally. // _values is set only during construction. if (null == _attrCache && null != attributes && 0 < attributes.Length) { _attrCache = new Dictionary<object, AttributeCollection>(); foreach (FieldDescriptor pd in _propertyDescriptors) { var o = pd.GetValue(this); var atts = o.GetType().GetCustomAttributes( /*inherit*/false); //atts will not be null (atts.Length==0) var attrArray = new Attribute[atts.Length]; atts.CopyTo(attrArray, 0); _attrCache.Add(pd, new AttributeCollection(attrArray)); } } //Create the filter based on the attributes. props = new PropertyDescriptorCollection(null); foreach (PropertyDescriptor pd in _propertyDescriptors) { if (_attrCache[pd].Matches(attributes)) { props.Add(pd); } } // Store the computed properties if (filtering) { cache = new FilterCache(); cache.Attributes = attributes; cache.FilteredProperties = props; _filterCache = cache; } return props; }
/// <summary> /// /// </summary> /// <param name="attributes"></param> /// <returns></returns> public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { // Retrieve cached properties and filtered properties var filtering = attributes != null && attributes.Length > 0; var cache = provider.filterCache; var props = provider.propCache; // Use a cached version if we can if (filtering && cache != null && cache.IsValid(attributes)) { return cache.FilteredProperties; } if (!filtering && props != null) { return props; } var properties1 = new Dictionary<string, PropertyDescriptor>(); { foreach (PropertyDescriptor prop in base.GetProperties()) { properties1[prop.Name] = prop; } } if (objectType.IsInterface) { foreach (var interfaceType in objectType.GetInterfaces()) { foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(interfaceType)) { properties1[prop.Name] = prop; } } } var properties = new ArrayList(properties1.Values); //Store the updated properties props = new PropertyDescriptorCollection( (PropertyDescriptor[])properties.ToArray(typeof(PropertyDescriptor)), false); if (filtering) { cache = new FilterCache { FilteredProperties = props, Attributes = attributes }; provider.filterCache = cache; } else provider.propCache = props; return props; }
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { // get the cached properties and filtered properties bool filtering = attributes != null && attributes.Length > 0; FilterCache cache = _provider._filteredCache; PropertyDescriptorCollection props = _provider._cachedProps; // use the cache if it's still valid if (filtering && cache != null && cache.IsValid(attributes)) { return cache.FilteredProperties; } else if (!filtering && props != null) { return props; } // create a new property collection props = new PropertyDescriptorCollection(null); // add the descriptions offered by default foreach (PropertyDescriptor prop in base.GetProperties(attributes)) { props.Add(prop); } // add descriptions for all the fields (filtered by attributes) foreach (FieldInfo field in _objectType.GetFields()) { FieldToPropertyDescriptor fieldDesc = new FieldToPropertyDescriptor(field); if (!filtering || fieldDesc.Attributes.Contains(attributes)) props.Add(fieldDesc); } // store the filtered properties in our cache if (filtering) { cache = new FilterCache(); cache.Attributes = attributes; cache.FilteredProperties = props; _provider._filteredCache = cache; } else { // update the reference to the new cache object _provider._cachedProps = props; } return props; }