有的时候,我们会使用到WeakList,它和传统的List不同的是,保存的是对象的弱应用,在WeakList中存储的对象会被GC回收,在一些和UI相关的编程的地方会用到它(弱事件,窗体的通知订阅等)。
.Net本身并没有提供WeakList,今天编程的时候用到了,便随手写了一个,支持添加、删除和遍历。当对象被GC的时候也会自动从WeakList中删除。由于是一个即时兴起的一个程序,没有经过什么测试, 发现有Bug的话再更新一下。这里记录一下,以备后续查询使用。
1 class WeakList: IEnumerable where T : class 2 { 3 Dictionary > _dic = new Dictionary >(); 4 ConditionalWeakTable _disposeActions = new ConditionalWeakTable (); 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 (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 getDataSource()38 {39 foreach (var refer in _dic.Values)40 {41 T data = null;42 43 if (!refer.TryGetTarget(out data))44 continue;45 else46 yield return data;47 }48 }49 50 public IEnumerator GetEnumerator()51 {52 return getDataSource().GetEnumerator();53 }54 55 IEnumerator IEnumerable.GetEnumerator()56 {57 return getDataSource().GetEnumerator();58 }59 60 class DisposeAction61 {62 Action _action;63 public DisposeAction(Action action)64 {65 _action = action;66 }67 68 ~DisposeAction()69 {70 _action();71 }72 }73 }