C # SortedSet <T>и равенство - PullRequest
       34

C # SortedSet <T>и равенство

12 голосов
/ 22 декабря 2011

Я немного озадачен поведением SortedSet, см. Следующий пример:

public class Blah
{
    public double Value { get; private set; }

    public Blah(double value)
    {
        Value = value;
    }
}

public class BlahComparer : Comparer<Blah>
{
    public override int Compare(Blah x, Blah y)
    {
        return Comparer<double>.Default.Compare(x.Value, y.Value);
    }
}

public static void main()
{
    var blahs = new List<Blah> {new Blah(1), new Blah(2), 
                                new Blah(3), new Blah(2)}

    //contains all 4 entries
    var set = new HashSet<Blah>(blahs); 

    //contains only Blah(1), Blah(2), Blah(3)
    var sortedset = new SortedSet<Blah>(blahs, new BlahComparer());
}

Поэтому SortedSet отбрасывает записи, если Compare (x, y) возвращает 0. Могу ли я предотвратить это, так что мой SortedSetведет себя как HashSet и отбрасывает записи, только если Equals () возвращает true?

Ответы [ 3 ]

8 голосов
/ 22 декабря 2011

Описание

SortedSet: У вас есть много элементов, которые необходимо сохранить, и вы хотите сохранить их в отсортированном порядке, а также исключить все дубликаты из структуры данных.Тип SortedSet, который является частью пространства имен System.Collections.Generic в языке C # и .NET Framework, обеспечивает эту функциональность.

Согласно MSDN Compare метод возвращает

  • Меньше нуля , если x меньше y.
  • Ноль , если x равно y.
  • Больше нуля , если x больше y.

Дополнительная информация

Обновление

Если ваш Blaкласс реализует IComparable, и вы хотите, чтобы ваш список был отсортирован, вы можете сделать это.

var blahs = new List<Blah> {new Blah(1), new Blah(2), 
                            new Blah(3), new Blah(2)};
blahs.Sort();

Если ваш Bla класс NOT реализует IComparable, и вы хотите, чтобы ваш список был отсортирован, вы можетедля этого используйте Linq (пространство имен System.Linq).

blahs = blahs.OrderBy(x => x.MyProperty).ToList();
5 голосов
/ 22 декабря 2011

Это можно сделать, если предоставить альтернативное сравнение, когда значения равны, а метод Compare в противном случае вернет 0. В большинстве случаев это, скорее всего, просто отложит проблему, а не решит ее. Как уже отмечали другие, SortedSet удаляет дубликаты, и когда вы предоставляете пользовательский компаратор, он использует его для определения дублирования.

    static void Main(string[] args)
    {
        var blahs = new List<Blah>
                        {
                            new Blah(1, 0), new Blah(2, 1),
                            new Blah(3, 2), new Blah(2, 3)
                        };

        blahs.Add(blahs[0]);

        //contains all 4 entries
        var set = new HashSet<Blah>(blahs);

        //contains all 4 entries
        var sortedset = new SortedSet<Blah>(blahs, new BlahComparer());

    }
}

public class Blah
{
    public double Value { get; private set; }

    public Blah(double value, int index)
    {
        Value = value;
        Index = index;
    }

    public int Index { get; private set; }

    public override string ToString()
    {
        return Value.ToString();
    }
}

public class BlahComparer : Comparer<Blah>
{
    public override int Compare(Blah x, Blah y)
    {
        // needs null checks
        var referenceEquals = ReferenceEquals(x, y);
        if (referenceEquals)
        {
            return 0;
        }
        var compare = Comparer<double>.Default.Compare(x.Value, y.Value);
        if (compare == 0)
        {
            compare = Comparer<int>.Default.Compare(x.Index, y.Index);
        }
        return compare;
    }
}
2 голосов
/ 22 декабря 2011

Вы не можете найти другой Blah(2), потому что вы используете Set.

Set - A collection of well defined and **distinct** objects
Например,

MultiSet позволяет дублировать объекты.

...