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
}
}