Я пытаюсь поиграть с отсортированными наборами в С# для пользовательских объектов, и по какой-то причине кажется, что отсортированные наборы могут не использовать ссылки на объекты для хранения данных.
В следующем фрагменте кода я использую пользовательский IComparer, чтобы полагаться на свойство Counts пользовательского класса. Но по какой-то причине это, похоже, влияет на функциональность добавления. и строка counter.Add(two) не вносит никаких дополнений в набор, даже если это другая ссылка и имеет разные значения для двух свойств.
Я что-то пропустил? У меня что-то не так в том, как SortedSets должны работать в С#?
Фрагмент кода
public class SortedStructureTesting
{
public void TestingSortedSets()
{
SortedSet<CounterSetup> counter = new SortedSet<CounterSetup>(new CompareCounts());
CounterSetup one = new CounterSetup(1);
CounterSetup two = new CounterSetup(2);
CounterSetup three = new CounterSetup(3, 2);
counter.Add(one);
counter.Add(two); // Does not work. This value does not get added to the set.
counter.Add(three);
var max = counter.Max;
counter.Remove(max);
var sec = counter.Max;
counter.Remove(sec);
}
public class CounterSetup
{
public static Random random = new Random();
public CounterSetup(int no, int cnt = 1)
{
Number = no;
Count = cnt;
Blah = new string(Guid.NewGuid().ToString());
}
public int Number { get; private set; }
public int Count { get; set; }
public string Blah { get; private set; }
}
public class CompareCounts : IComparer<CounterSetup>
{
public int Compare(CounterSetup one, CounterSetup two)
{
return one.Count.CompareTo(two.Count);
}
}
}
Спасибо, что заглянули и помогли!
Похоже, SortedSet принимает только уникальные значения для Sort-Property.
Привет, @DmitryBychenko, спасибо, что так быстро ответили мне! Я думал, что отсортированный набор будет обрабатывать уникальность на основе пользовательской ссылки на объект, используя свойство сортировки для сохранения сортировки объектов. Разве это невозможно?
@Nikolaus, да .. по какой-то причине определенно кажется, что ссылка не используется для уникальности .. Не знаете ли вы, есть ли какая-нибудь структура, которую я мог бы использовать для поддержания уникальности на основе одного свойства и сортировки с использованием другого ? без, понимаете, создания собственной структуры данных?
@devNull ДА! Спасибо!
Ну [Sorted]Set
может содержать только отдельные элементы; то есть Set
не может иметь еще два одинаковых элемента. Вы сравниваете предмет (рассматриваете их как равные) в отношении Count
: если два предмета имеют одинаковые Count
, они считаются равными. В вашем коде
CounterSetup one = new CounterSetup(1); // one.Count == 1
CounterSetup two = new CounterSetup(2); // two.Count == 1
CounterSetup three = new CounterSetup(3, 2); // three.Count == 2
у вас есть one.Count == two.Count == 1
, поэтому one
и two
равны для отсортированного набора counter
. Когда вы добавляете элементы, второй (то есть two
) игнорируется:
counter.Add(one);
counter.Add(two); // Ignored: there's already an item (one) with the same Count
counter.Add(three);
Если вам нужны отдельные критерии (один для Equals
, а другой для порядка), вы можете попробовать старый добрый HashSet
, который вы можете представить как заказанный с помощью Linq:
using System.Linq;
...
// Items in counter are unique (based on MyEqualityComparer)
HashSet<CounterSetup> counter = new HashSet<CounterSetup>(
new MyEqualityComparer()
);
// Now we order counter items by different criterium (here we sort by `Count`)
var ordered = counter
.OrderBy(item => item.Count);
Привет, @Dmitry, я понимаю, что ты имеешь в виду.. Но это выглядит очень странно.. В конце концов, если мы используем HashSet<CounterSetup> counter = new HashSet<CounterSetup>(); у нас есть все эти 3 объекта там. Есть ли способ получить все 3 объекта в отсортированном наборе (или какой-либо другой отсортированной коллекции) и при этом отсортировать их по другому свойству?
Привет, Дмитрий, последнее редактирование твоего поста определенно помогает мне решить мои проблемы! Спасибо!!
@rmehta: увы, SortedSet<T>
это RB-Tree (Red Black Tree) и он должен работать с одним критерием.
Ах! Понятно... красно-черное дерево с 1 критерием действительно многое объясняет... спасибо, что выручили меня в этот странный час!
[Sorted]Set
не может быть двух или более одинаковых предметов. Вы сравниваетеitem
s сCount
; поэтомуCount
должен быть различен. Обратите внимание, что экземплярыone
иtwo
имеют одинаковыеCount == 1
, поэтомуtwo
проигнорировано (не добавлено)