2010-02-04 10 views
14

Che cosa è unLista Unica <T> in .NET 2

  • preferibilmente generici;
  • unica (IComparable/IEquitable) valutati

collezione di oggetti per la NET 2?

(à laList<T>, o di un equivalente di HashSet<T> da NET 3.5, ma senza articoli ordinati)

+1

Vedere http://stackoverflow.com/questions/687034/using-hashset-in-c-2-0-compatible-with-3-5. –

+1

Perché metti "à la' Lista '" nella tua domanda? Non è un elenco di articoli unici. – herzmeister

+1

Se sei un h4x0r malvagio, puoi semplicemente installare il singolo assembly System.Core.dll con la tua applicazione. Non è necessario installare il framework .NET 3.5 completo. – herzmeister

risposta

8

Sfortunatamente, la prima buona classe di sistema per questo è la HashSet, con cui si avrà accesso solo con .Net 3.5.

Se sei bloccato nelle versioni precedenti, le opzioni non sono così belle. Il più comune è usare un tipo di dizionario in cui la chiave è il valore che si sta tentando di memorizzare. Puoi avvolgerlo facilmente nella tua classe.

Se siete disposti a uscire dal framework tutti insieme, ci sono raccolte di strutture dati per .Net, come ad esempio NGenerics.

+0

Grazie per questo. Ho usato System.Collections.Generic.Dictionary per ottenere esattamente l'effetto di cui avevo bisogno. L'ho avvolto in un try/catch (ArgumentException) –

+0

Esiste una coda unica in .Net 4.0, ad es. se una coda contiene 1 a qualsiasi livello e si tenta di aggiungere nuovamente 1 dovrebbe generare un errore. –

+1

@MubasharAhmad No, non è un requisito comune e probabilmente non verrà mai aggiunto al framework. È sempre possibile creare questo comportamento avendo sia una coda che un hashset e quindi aggiornare entrambi su qualsiasi operazione. –

3

Quello che vi serve è un insieme, per quanto mi ricordo che c'era alcuna implementazione Situato in 2.0. Puoi controllare this.

Edit: Se davvero si vuole implementare il proprio, qualcosa di simile sarebbe fare il lavoro a scapito delle prestazioni su inserti: (non ho testare la funzionalità)

class UniqueList<T> : IList<T> 
{ 
    private IList<T> m_InternalList; 

    public UniqueList(IList<T> list) 
    { 
     m_InternalList = list; 
    } 

    public System.Collections.ObjectModel.ReadOnlyCollection<T> AsReadOnly() 
    { 
     return new System.Collections.ObjectModel.ReadOnlyCollection<T>(this); 
    } 

    #region IList<T> Members 

    public int IndexOf(T item) 
    { 
     return m_InternalList.IndexOf(item); 
    } 

    public void Insert(int index, T item) 
    { 
     if (!m_InternalList.Contains(item)) 
      m_InternalList.Insert(index, item); 
    } 

    public void RemoveAt(int index) 
    { 
     m_InternalList.RemoveAt(index); 
    } 

    public T this[int index] 
    { 
     get 
     { 
      return m_InternalList[index]; 
     } 
     set 
     { 
      if (!m_InternalList.Contains(value)) 
       m_InternalList[index] = value; 
     } 
    } 

    #endregion 

    #region ICollection<T> Members 

    public void Add(T item) 
    { 
     if (!m_InternalList.Contains(item)) 
      m_InternalList.Add(item); 
    } 

    public void Clear() 
    { 
     m_InternalList.Clear(); 
    } 

    public bool Contains(T item) 
    { 
     return m_InternalList.Contains(item); 
    } 

    public void CopyTo(T[] array, int arrayIndex) 
    { 
     m_InternalList.CopyTo(array, arrayIndex); 
    } 

    public int Count 
    { 
     get { return m_InternalList.Count; } 
    } 

    public bool IsReadOnly 
    { 
     get { return m_InternalList.IsReadOnly; } 
    } 

    public bool Remove(T item) 
    { 
     return m_InternalList.Remove(item); 
    } 

    #endregion 

    #region IEnumerable<T> Members 

    public IEnumerator<T> GetEnumerator() 
    { 
     return m_InternalList.GetEnumerator(); 
    } 

    #endregion 

    #region IEnumerable Members 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return m_InternalList.GetEnumerator(); 
    } 

    #endregion 
} 
+0

per me è una soluzione un po '"difficile" per importare un progetto "esterno" solo per una collezione unica. Preferisco o scrivere una collezione personalizzata da solo o una soluzione migliore, basta usare un "trucco" sulle classi framework esistenti. – serhio

+4

@serhio: Penso che scrivere la propria classe di raccolta sia "più difficile", quindi fare riferimento a un componente di terze parti che ha dimostrato di funzionare. Penso che tu soffra della sindrome del "non inventato qui". :) –

+0

un metodo che ho veramente bisogno è '.AsReadOnly()' – serhio

1

Abbiamo usato per usare PowerCollections Impostare la classe per quello in .NET 2. Ha funzionato abbastanza bene. C'era un sacco di cose belle in biblioteca.

2

È possibile utilizzare la raccolta HashedSet<T> definita nell'assieme Iesi.Collections. Questo è un progetto open source, che viene utilizzato anche da NHibernate.