diff --git a/src/Weakly/Collections/WeakCollection.cs b/src/Weakly/Collections/WeakCollection.cs index ea874d1..a045406 100644 --- a/src/Weakly/Collections/WeakCollection.cs +++ b/src/Weakly/Collections/WeakCollection.cs @@ -21,12 +21,7 @@ private void CleanIfNeeded() return; _gcSentinel.Target = new object(); - - for (var i = _inner.Count - 1; i >= 0; i--) - { - if (!_inner[i].IsAlive) - _inner.RemoveAt(i); - } + Purge(); } #region Constructors @@ -59,6 +54,15 @@ public WeakCollection(int capacity) #endregion + /// + /// Removes all dead entries. + /// + /// true if entries where removed; otherwise false. + public bool Purge() + { + return _inner.RemoveAll(l => !l.IsAlive) > 0; + } + /// /// Returns an enumerator that iterates through the collection. /// @@ -66,6 +70,7 @@ public WeakCollection(int capacity) public IEnumerator GetEnumerator() { CleanIfNeeded(); + var enumerable = _inner.Select(item => (T) item.Target) .Where(value => value != null); return enumerable.GetEnumerator(); @@ -102,7 +107,7 @@ public void Clear() public bool Contains(T item) { CleanIfNeeded(); - return _inner.Any(w => ((T)w.Target) == item); + return _inner.FindIndex(w => ((T) w.Target) == item) >= 0; } /// @@ -112,14 +117,20 @@ public bool Contains(T item) /// The zero-based index in array at which copying begins. public void CopyTo(T[] array, int arrayIndex) { + CleanIfNeeded(); + if (array == null) throw new ArgumentNullException("array"); if (arrayIndex < 0 || arrayIndex >= array.Length) throw new ArgumentOutOfRangeException("arrayIndex"); - if ((arrayIndex + Count) > array.Length) + if ((arrayIndex + _inner.Count) > array.Length) throw new ArgumentException("The number of elements in the source collection is greater than the available space from arrayIndex to the end of the destination array."); - this.ToArray().CopyTo(array, arrayIndex); + var items = _inner.Select(item => (T) item.Target) + .Where(value => value != null) + .ToArray(); + + items.CopyTo(array, arrayIndex); } /// diff --git a/src/Weakly/Collections/WeakValueDictionary.cs b/src/Weakly/Collections/WeakValueDictionary.cs index 5878127..39810ea 100644 --- a/src/Weakly/Collections/WeakValueDictionary.cs +++ b/src/Weakly/Collections/WeakValueDictionary.cs @@ -22,15 +22,7 @@ private void CleanIfNeeded() return; _gcSentinel.Target = new object(); - - var keysToRemove = _inner.Where(pair => !pair.Value.IsAlive) - .Select(pair => pair.Key) - .ToList(); - - foreach (var key in keysToRemove) - { - _inner.Remove(key); - } + Purge(); } #region Constructors @@ -102,6 +94,24 @@ public WeakValueDictionary(int capacity, IEqualityComparer comparer) #endregion + /// + /// Removes all dead entries. + /// + /// true if entries where removed; otherwise false. + public bool Purge() + { + var keysToRemove = _inner.Where(pair => !pair.Value.IsAlive) + .Select(pair => pair.Key) + .ToArray(); + + foreach (var key in keysToRemove) + { + _inner.Remove(key); + } + + return keysToRemove.Length > 0; + } + /// /// Returns an enumerator that iterates through the . /// @@ -109,6 +119,7 @@ public WeakValueDictionary(int capacity, IEqualityComparer comparer) public IEnumerator> GetEnumerator() { CleanIfNeeded(); + var enumerable = _inner.Select(pair => new KeyValuePair(pair.Key, (TValue) pair.Value.Target)) .Where(pair => pair.Value != null); return enumerable.GetEnumerator(); @@ -143,14 +154,20 @@ bool ICollection>.Contains(KeyValuePair void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) { + CleanIfNeeded(); + if (array == null) throw new ArgumentNullException("array"); if (arrayIndex < 0 || arrayIndex >= array.Length) throw new ArgumentOutOfRangeException("arrayIndex"); - if ((arrayIndex + Count) > array.Length) + if ((arrayIndex + _inner.Count) > array.Length) throw new ArgumentException("The number of elements in the source collection is greater than the available space from arrayIndex to the end of the destination array."); - this.ToArray().CopyTo(array, arrayIndex); + var items = _inner.Select(pair => new KeyValuePair(pair.Key, (TValue) pair.Value.Target)) + .Where(pair => pair.Value != null) + .ToArray(); + + items.CopyTo(array, arrayIndex); } bool ICollection>.Remove(KeyValuePair item) @@ -238,15 +255,13 @@ public bool TryGetValue(TKey key, out TValue value) return false; } - var result = (TValue) wr.Target; - if (result == null) + value = (TValue) wr.Target; + if (value == null) { _inner.Remove(key); - value = null; return false; } - value = result; return true; } @@ -332,10 +347,13 @@ public void CopyTo(TValue[] array, int arrayIndex) throw new ArgumentNullException("array"); if (arrayIndex < 0 || arrayIndex >= array.Length) throw new ArgumentOutOfRangeException("arrayIndex"); - if ((arrayIndex + Count) > array.Length) + if ((arrayIndex + _inner.Count) > array.Length) throw new ArgumentException("The number of elements in the source collection is greater than the available space from arrayIndex to the end of the destination array."); - this.ToArray().CopyTo(array, arrayIndex); + var items = _inner.Select(pair => pair.Value) + .ToArray(); + + items.CopyTo(array, arrayIndex); } bool ICollection.Remove(TValue item) diff --git a/src/Weakly/Events/WeakEventList.cs b/src/Weakly/Events/WeakEventList.cs index ceda8d8..1b46fac 100644 --- a/src/Weakly/Events/WeakEventList.cs +++ b/src/Weakly/Events/WeakEventList.cs @@ -94,18 +94,7 @@ public void RemoveHandler(Delegate handler) public bool Purge() { - var foundDirt = false; - - for (var i = _list.Count - 1; i >= 0; --i) - { - if (_list[i].Target == null) - { - _list.RemoveAt(i); - foundDirt = true; - } - } - - return foundDirt; + return _list.RemoveAll(l => l.Target == null) > 0; } public List GetCopy()