using System; using System.Collections; using System.Collections.Generic; namespace Developpez.Dotnet.Collections { /// /// Représente une liste fortement typée d'objets accessibles par index. Fournit des méthodes de recherche, de tri et de manipulation de listes.
/// Cette classe est thread-safe ///
/// Type des éléments de la liste public class SyncList : IList, ICollection { #region Internals readonly object _syncRoot = new object(); /// /// Objet de synchronisation /// public virtual object SyncRoot { get { return _syncRoot; } } private readonly List _internalList; /// /// Liste utilisée en interne pour stocker les valeurs /// protected virtual List InternalList { get { return _internalList; } } #endregion /// /// Initialise une nouvelle instance de la classe /// public SyncList() { _internalList = new List(); } /// /// Initialise une nouvelle instance de la classe qui contient des éléments copiés à partir de la collection spécifiée et qui possède une capacité suffisante pour accepter le nombre d'éléments copiés. /// /// Collection dont les éléments sont copiés dans la nouvelle liste. public SyncList(IEnumerable collection) { _internalList = new List(collection); } /// /// Initialise une nouvelle instance de la classe qui est vide et a la capacité initiale spécifiée. /// /// Capacité initiale de la liste public SyncList(int capacity) { _internalList = new List(capacity); } #region IList Membres /// /// Renvoi l'index d'un élément présent dans la liste, ou -1 s'il n'a pas été trouvé /// /// Element à rechercher /// Index de l'élément s'il a été trouvé, ou -1 sinon public virtual int IndexOf(T item) { lock (SyncRoot) { return InternalList.IndexOf(item); } } /// /// Insère un élément à la position indiquée /// /// Position à laquelle insérer un élément /// Elément à insérer public virtual void Insert(int index, T item) { lock (SyncRoot) { InternalList.Insert(index, item); } } /// /// Retire l'élément présent à l'indice de base zéro index de la liste /// /// indice de l'élément à retirer de la liste public virtual void RemoveAt(int index) { lock (SyncRoot) { InternalList.RemoveAt(index); } } /// /// Obtient ou définit l'élément à l'indice de base zéro index /// /// indice de l'élément /// élément à l'indice de base zéro index public virtual T this[int index] { get { lock (SyncRoot) { return InternalList[index]; } } set { lock (SyncRoot) { InternalList[index] = value; } } } #endregion #region ICollection Membres /// /// Ajoute un objet à la fin de /// /// Element à rajouter public virtual void Add(T item) { lock (SyncRoot) { InternalList.Add(item); } } /// /// Supprime tous les éléments de /// public virtual void Clear() { lock (SyncRoot) { InternalList.Clear(); } } /// /// Détermine si un élément est dans /// /// Objet à trouver dans . La valeur peut être une référence null (Nothing en Visual Basic) pour les types référence. /// true si item existe dans ; sinon, false public virtual bool Contains(T item) { lock (SyncRoot) { return InternalList.Contains(item); } } /// /// Copie l'ensemble du vers un tableau compatible unidimensionnel, en commençant à l'index spécifié du tableau cible. /// /// Array unidimensionnel qui constitue la destination des éléments copiés à partir de . Array doit avoir une indexation de base zéro. /// Index de base zéro dans array au niveau duquel commencer la copie. public virtual void CopyTo(T[] array, int arrayIndex) { lock (SyncRoot) { InternalList.CopyTo(array, arrayIndex); } } /// /// Renvoi le nombre d'éléments actuellement présents dans la liste /// public virtual int Count { get { lock (SyncRoot) { return InternalList.Count; } } } /// /// Indique si la liste est en lecture seule /// public virtual bool IsReadOnly { get { return false; } } /// /// Supprime la première occurrence d'un objet spécifique de . /// /// Objet à supprimer de . La valeur peut être une référence null (Nothing en Visual Basic) pour les types référence. /// true si la suppression de item est réussie ; sinon, false. Cette méthode retourne également false si item est introuvable dans . public virtual bool Remove(T item) { lock (SyncRoot) { return InternalList.Remove(item); } } #endregion #region IEnumerable Membres /// /// Retourne un énumérateur qui parcourt . /// /// pour . public virtual IEnumerator GetEnumerator() { IEnumerator enumerator; lock(SyncRoot) { enumerator = InternalList.GetEnumerator(); } return new SynchronizedEnumerator(this, enumerator); } /// /// Enumerateur thread-safe pour /// public class SynchronizedEnumerator : IEnumerator { /// /// Liste utilisée en interne pour récupérer les valeurs /// private readonly SyncList _ownedList; /// /// Enumérateur non thread safe de la liste parente /// private readonly IEnumerator _enumerator; /// /// Initialise une nouvelle instance de l'énumérateur /// /// Liste à utiliser pour l'énumération /// Enumérateur utilisé pour l'opération public SynchronizedEnumerator(SyncList ownedList, IEnumerator enumerator) { this._ownedList = ownedList; this._enumerator = enumerator; } #region IEnumerator Membres /// /// Obtient l'élément actuel dans la collection. /// public T Current { get { lock (_ownedList.SyncRoot) { return _enumerator.Current; } } } #endregion #region IDisposable Membres /// /// Libère toutes les ressources utilisées par cet objet /// public void Dispose() { _enumerator.Dispose(); } #endregion #region IEnumerator Membres /// /// Obtient l'élément actuel dans la collection. /// object IEnumerator.Current { get { return ((IEnumerator)this).Current; } } /// /// Avance l'énumérateur à l'élément suivant de la collection. /// /// true si l'énumérateur a pu avancer jusqu'à l'élément suivant ; false si l'énumérateur a dépassé la fin de la collection. public bool MoveNext() { lock (_ownedList.SyncRoot) { return _enumerator.MoveNext(); } } /// /// Rétablit l'énumérateur à sa position initiale, qui précède le premier élément de la collection. /// public void Reset() { lock (_ownedList.SyncRoot) { _enumerator.Reset(); } } #endregion } #endregion #region IEnumerable Membres /// /// Retourne un énumérateur qui parcourt . /// /// pour . IEnumerator IEnumerable.GetEnumerator() { return ((IList)this).GetEnumerator(); } #endregion #region ICollection Membres /// /// Copie les éléments de ICollection dans Array, en commençant à un index particulier de Array. /// /// Array unidimensionnel qui constitue la destination des éléments copiés à partir de ICollection. Array doit avoir une indexation de base zéro. /// Index de base zéro dans array au niveau duquel commencer la copie. public virtual void CopyTo(Array array, int index) { T[] lst; lock (SyncRoot) { lst = InternalList.ToArray(); } lst.CopyTo(array, index); } /// /// Indique si la liste est synchronisée /// public virtual bool IsSynchronized { get { return true; } } #endregion } }