// ----------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. // ----------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Microsoft.Internal; using Microsoft.Internal.Collections; namespace Microsoft.Internal.Collections { internal class WeakReferenceCollection where T : class { private readonly List _items = new List(); public void Add(T item) { // Only cleanup right before we need to reallocate space. if (this._items.Capacity == this._items.Count) { this.CleanupDeadReferences(); } this._items.Add(new WeakReference(item)); } public void Remove(T item) { int index = IndexOf(item); if (index != -1) { this._items.RemoveAt(index); } } public bool Contains(T item) { return IndexOf(item) >= 0; } public void Clear() { this._items.Clear(); } // Should be executed under at least a read lock. private int IndexOf(T item) { int count = this._items.Count; for (int i = 0; i < count; i++) { if (this._items[i].Target == item) { return i; } } return -1; } // Should be executed under a write lock private void CleanupDeadReferences() { int count = this._items.Count; for (int i = count - 1; i >= 0; i--) { if (this._items[i].Target == null) { this._items.RemoveAt(i); } } } public List AliveItemsToList() { List aliveItems = new List(); foreach (var weakItem in this._items) { T item = weakItem.Target as T; if (item != null) { aliveItems.Add(item); } } return aliveItems; } } }