// // // // // $Revision$ // using System; using System.Collections.Generic; using System.Threading; namespace ICSharpCode.TextEditor.Util { /// /// A IList{T} that checks that it is only accessed on the thread that created it, and that /// it is not modified while an enumerator is running. /// sealed class CheckedList : IList { readonly int threadID; readonly IList baseList; int enumeratorCount; public CheckedList() : this(new List()) {} public CheckedList(IList baseList) { if (baseList == null) throw new ArgumentNullException("baseList"); this.baseList = baseList; this.threadID = Thread.CurrentThread.ManagedThreadId; } void CheckRead() { if (Thread.CurrentThread.ManagedThreadId != threadID) throw new InvalidOperationException("CheckList cannot be accessed from this thread!"); } void CheckWrite() { if (Thread.CurrentThread.ManagedThreadId != threadID) throw new InvalidOperationException("CheckList cannot be accessed from this thread!"); if (enumeratorCount != 0) throw new InvalidOperationException("CheckList cannot be written to while enumerators are active!"); } public T this[int index] { get { CheckRead(); return baseList[index]; } set { CheckWrite(); baseList[index] = value; } } public int Count { get { CheckRead(); return baseList.Count; } } public bool IsReadOnly { get { CheckRead(); return baseList.IsReadOnly; } } public int IndexOf(T item) { CheckRead(); return baseList.IndexOf(item); } public void Insert(int index, T item) { CheckWrite(); baseList.Insert(index, item); } public void RemoveAt(int index) { CheckWrite(); baseList.RemoveAt(index); } public void Add(T item) { CheckWrite(); baseList.Add(item); } public void Clear() { CheckWrite(); baseList.Clear(); } public bool Contains(T item) { CheckRead(); return baseList.Contains(item); } public void CopyTo(T[] array, int arrayIndex) { CheckRead(); baseList.CopyTo(array, arrayIndex); } public bool Remove(T item) { CheckWrite(); return baseList.Remove(item); } public IEnumerator GetEnumerator() { CheckRead(); return Enumerate(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { CheckRead(); return Enumerate(); } IEnumerator Enumerate() { CheckRead(); try { enumeratorCount++; foreach (T val in baseList) { yield return val; CheckRead(); } } finally { enumeratorCount--; CheckRead(); } } } }