有的时候,我们会使用到WeakList,它和传统的List不同的是,保存的是对象的弱应用,在WeakList中存储的对象会被GC回收,在一些和UI相关的编程的地方会用到它(弱事件,窗体的通知订阅等)。
.Net本身并没有提供WeakList,今天编程的时候用到了,便随手写了一个,支持添加、删除和遍历。当对象被GC的时候也会自动从WeakList中删除。由于是一个即时兴起的一个程序,没有经过什么测试, 发现有Bug的话再更新一下。这里记录一下,以备后续查询使用。
1 class WeakList<T> : IEnumerable<T> where T : class 2 { 3 Dictionary<long, WeakReference<T>> _dic = new Dictionary<long, WeakReference<T>>(); 4 ConditionalWeakTable<T, DisposeAction> _disposeActions = new ConditionalWeakTable<T, DisposeAction>(); 5 6 public int Count { get { return _dic.Count; } } 7 8 [MethodImpl] 9 public void Add(T item) 10 { 11 var id = getObjectId(item); 12 13 _dic.Add(id, new WeakReference<T>(item)); 14 _disposeActions.Add(item, new DisposeAction(() => removeObsolete(id))); 15 } 16 17 [MethodImpl] 18 public void Remove(T item) 19 { 20 var id = getObjectId(item); 21 22 _dic.Remove(id); 23 _disposeActions.Remove(item); 24 } 25 26 [MethodImpl] 27 void removeObsolete(long id) 28 { 29 _dic.Remove(id); 30 } 31 32 long getObjectId(T item) 33 { 34 return RuntimeHelpers.GetHashCode(item); 35 } 36 37 IEnumerable<T> getDataSource() 38 { 39 foreach (var refer in _dic.Values) 40 { 41 T data = null; 42 43 if (!refer.TryGetTarget(out data)) 44 continue; 45 else 46 yield return data; 47 } 48 } 49 50 public IEnumerator<T> GetEnumerator() 51 { 52 return getDataSource().GetEnumerator(); 53 } 54 55 IEnumerator IEnumerable.GetEnumerator() 56 { 57 return getDataSource().GetEnumerator(); 58 } 59 60 class DisposeAction 61 { 62 Action _action; 63 public DisposeAction(Action action) 64 { 65 _action = action; 66 } 67 68 ~DisposeAction() 69 { 70 _action(); 71 } 72 } 73 }