Existe-t-il une collection en C # qui ne vous permette pas d'y ajouter des éléments en double? Par exemple, avec la classe idiote de
public class Customer {
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public override int GetHashCode() {
return (FirstName + LastName + Address).GetHashCode();
}
public override bool Equals(object obj) {
Customer C = obj as Customer;
return C != null && String.Equals(this.FirstName, C.FirstName) && String.Equals(this.LastName, C.LastName) && String.Equals(this.Address, C.Address);
}
}
Le code suivant lève (évidemment) une exception:
Customer Adam = new Customer { Address = "A", FirstName = "Adam", LastName = "" };
Customer AdamDup = new Customer { Address = "A", FirstName = "Adam", LastName = "" };
Dictionary<Customer, bool> CustomerHash = new Dictionary<Customer, bool>();
CustomerHash.Add(Adam, true);
CustomerHash.Add(AdamDup, true);
Mais existe-t-il une classe qui garantira de la même manière l'unicité, mais sans KeyValuePairs? J'ai pensé HashSet<T>
ferait cela, mais après avoir lu la documentation, il semblerait que la classe ne soit qu'une implémentation définie (voir figure).
HashSet<T>
Est ce que vous recherchez. De MSDN (emphase ajoutée):
La classe
HashSet<T>
Fournit des opérations d'ensemble performantes. Un ensemble est une collection qui ne contient aucun élément en double et dont les éléments ne sont dans aucun ordre particulier.
Notez que la méthode HashSet<T>.Add(T item)
) renvoie un bool
- true
si l'élément a été ajouté à la collection; false
si l'élément était déjà présent.
Que diriez-vous d'une méthode d'extension sur HashSet?
public static void AddOrThrow<T>(this HashSet<T> hash, T item)
{
if (!hash.Add(item))
throw new ValueExistingException();
}
Du HashSet<T>
page sur MSDN:
La classe HashSet (Of T) fournit des opérations d'ensemble performantes. Un ensemble est une collection qui ne contient aucun élément en double et dont les éléments ne sont dans aucun ordre particulier.
(c'est moi qui souligne)
Si tout ce dont vous avez besoin est de garantir l'unicité des éléments, alors HashSet est ce qu'il vous faut.
Que voulez-vous dire quand vous dites "juste une implémentation définie"? Un ensemble est (par définition) une collection d'éléments uniques qui n'enregistre pas l'ordre des éléments.
Juste pour ajouter mes 2 centimes ...
si vous avez besoin d'un jeton ValueExistingException HashSet<T>
vous pouvez également créer facilement votre collection:
public class ThrowingHashSet<T> : ICollection<T>
{
private HashSet<T> innerHash = new HashSet<T>();
public void Add(T item)
{
if (!innerHash.Add(item))
throw new ValueExistingException();
}
public void Clear()
{
innerHash.Clear();
}
public bool Contains(T item)
{
return innerHash.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
innerHash.CopyTo(array, arrayIndex);
}
public int Count
{
get { return innerHash.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(T item)
{
return innerHash.Remove(item);
}
public IEnumerator<T> GetEnumerator()
{
return innerHash.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
cela peut être utile par exemple si vous en avez besoin à plusieurs endroits ...
Tu peux essayer HashSet<T>
Vous pouvez regarder dans quelque chose comme une liste unique comme suit
public class UniqueList<T>
{
public List<T> List
{
get;
private set;
}
List<T> _internalList;
public static UniqueList<T> NewList
{
get
{
return new UniqueList<T>();
}
}
private UniqueList()
{
_internalList = new List<T>();
List = new List<T>();
}
public void Add(T value)
{
List.Clear();
_internalList.Add(value);
List.AddRange(_internalList.Distinct());
//return List;
}
public void Add(params T[] values)
{
List.Clear();
_internalList.AddRange(values);
List.AddRange(_internalList.Distinct());
// return List;
}
public bool Has(T value)
{
return List.Contains(value);
}
}
et vous pouvez l'utiliser comme suit
var uniquelist = UniqueList<string>.NewList;
uniquelist.Add("abc","def","ghi","jkl","mno");
uniquelist.Add("abc","jkl");
var _myList = uniquelist.List;
ne retournera que "abc","def","ghi","jkl","mno"
toujours même lorsque des doublons y sont ajoutés