Soru .NET'te yalnızca benzersiz öğelere izin veren koleksiyon?


C # içinde koleksiyon öğeleri eklemenize izin vermeyecek bir koleksiyon var mı? Örneğin, aptal sınıfı ile

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

Aşağıdaki kod (belli ki) bir istisna atar:

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);

Ama benzerlikle benzersizliği garanti edecek bir sınıf var, ama KeyValuePairs olmadan? düşündüm HashSet<T> Bunu yapar, ancak belgeleri okuduktan sonra sınıfın sadece bir uygulama olduğu görülmektedir (git rakam).


76
2018-03-01 17:08


Menşei


Senin problemini anlamıyorum HashSet<T>. MSDN, "HashSet <T> sınıfı, yüksek performanslı küme işlemleri sağlar. Bir küme, yinelenen öğeler içermeyen ve öğeleri belirli bir sırada olmayan bir koleksiyondur." - Daniel Hilgarth
Daha fazla nedenini açıklayabilir misin HashSet<T> Yetersiz? - JaredPar
@mootinator: The Dictionary<K,V> sınıf değil her türlü siparişi garanti eder. - LukeH
Sadece varolan bir değer eklemeye çalıştığınızda bir istisna atmak istiyor sanırım ... Bunu yapmak için, yalnızca döndüğünüz bool değerini kontrol edin. HashSet<T>.Add yöntem ve atmak false... - digEmAll
Ayrıca, yalnızca bunları aşırı yüklemeye şiddetle tavsiye değişmez sadece türler. Değişken Müşteri, varsayılan Referans eşitliği ile genellikle daha iyi olur. - Henk Holterman


Cevaplar:


HashSet<T> aradığın şey. itibaren MSDN (vurgu eklendi):

HashSet<T> sınıf, yüksek performanslı set işlemleri sağlar. Bir set bir koleksiyon yinelenen öğe içermiyorve kimin belli bir düzende olmadığı.

Unutmayın ki HashSet<T>.Add(T item) yöntem bir döndürür bool - true öğe koleksiyona eklenmişse; false Öğe zaten mevcutsa.


159
2018-03-01 17:12





HashSet'te sadece bir uzantı yöntemine ne dersiniz?

public static void AddOrThrow<T>(this HashSet<T> hash, T item)
{
    if (!hash.Add(item))
        throw new ValueExistingException();
}

16
2017-07-03 20:14





İtibaren HashSet<T> MSDN'de sayfa:

HashSet (Of T) sınıfı, yüksek performanslı set işlemleri sağlar. Küme, yinelenen öğe içermeyen bir koleksiyondurve kimin belli bir düzende olmadığı.

(vurgun)


10
2018-03-01 17:11





Deneyebilirsin HashSet<T>


4
2018-03-01 17:11



meta.stackoverflow.com/tags/link-only-answers/info - Jonathon Reinhart


İhtiyacınız olan tek şey elemanların benzersizliğini sağlamaksa, HashSet ihtiyacınız olan şeydir.

“Sadece bir uygulama” dediğinizde ne demek istiyorsunuz? Bir set (tanım olarak), eleman siparişini kaydetmeyen benzersiz elemanların bir koleksiyonudur.


3
2018-03-01 17:13



Tamamen haklısın; soru biraz aptaldı. Temel olarak, bir yinelenen eklendiğinde (Sözlük <TKey, TValue> gibi) bir istisna atacak bir şey arıyordum, ancak daha önce de belirttiğim gibi, HashSet <T> yinelenen bir eklenti üzerinde false değerini döndürüyor. +1, teşekkürler. - Adam Rackis


Sadece 2 sentümü eklemek için ...

Eğer bir ValueExistingException-throwing'e ihtiyacınız varsa HashSet<T> Ayrıca koleksiyonunuzu kolayca oluşturabilirsiniz:

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();
    }
}

Bu, örneğin birçok yerde ihtiyacınız varsa yararlı olabilir ...


1
2018-03-01 19:03



Emin. Bir şey yapılıp yapılmadığını merak ettim ama teşekkür ederim +1 - Adam Rackis