/// <summary> /// Synchronize the destination collection to match the source collection. /// </summary> /// <param name="dest"></param> /// <param name="source"></param> public void Synchronize(ICollection <TDestItem> dest, ICollection <TSourceItem> source) { List <TDestItem> existing = new List <TDestItem>(dest); List <TDestItem> unProcessed = new List <TDestItem>(dest); CollectionUtils.ForEach(source, delegate(TSourceItem sourceItem) { // Find a pre-existing item that matches the source item TDestItem existingItem = CollectionUtils.SelectFirst(existing, delegate(TDestItem destItem) { return(CompareItems(destItem, sourceItem)); }); if (existingItem == null) { // Add a new dest item AddItem(sourceItem, dest); } else { // Update the existing attachment if (_allowUpdate) { UpdateItem(existingItem, sourceItem, dest); } // and remove from un-processed list unProcessed.Remove(existingItem); } }); // Any items in the dest list that are not in the source list are considered "deleted" if (unProcessed.Count > 0) { if (_allowRemove) { CollectionUtils.ForEach(unProcessed, delegate(TDestItem destItem) { RemoveItem(destItem, dest); }); } } }
/// <summary> /// Searches a type/method/property/field for attributes of the specified type, returning the first match. /// </summary> /// <typeparam name="TAttribute">The type of attribute (may also be a base class).</typeparam> /// <param name="member">The type/method/property/field to find attributes on.</param> /// <param name="inherit">True to include inherited attributes in the search.</param> /// <param name="filter">A filter that restricts the results of the search.</param> /// <returns>The first matching attribute instance, or null if no matches are found.</returns> public static TAttribute GetAttribute <TAttribute>(MemberInfo member, bool inherit, Predicate <TAttribute> filter) where TAttribute : Attribute { return(CollectionUtils.SelectFirst <TAttribute>(member.GetCustomAttributes(typeof(TAttribute), inherit), filter)); }