Jak posortowane zestawy dla języka C # działają z obiektami niestandardowymi? [duplikować]

Dec 14 2020

Próbuję bawić się posortowanymi zestawami w języku c # dla obiektów niestandardowych iz jakiegoś powodu wydaje się, że posortowane zestawy mogą nie używać odwołań do obiektów do przechowywania danych.

W poniższym fragmencie kodu używam niestandardowego IComparer, aby polegać na właściwości Counts klasy niestandardowej. Ale z jakiegoś powodu wydaje się to wpływać na funkcjonalność dodawania. i licznik. Linia Add (two) nie dodaje żadnego dodatku do zbioru, mimo że jest to inne odwołanie i ma inną wartość dla dwóch właściwości.

Czy coś mi brakuje? Czy coś jest nie tak z tym, jak SortedSets mają działać w C #?

Fragment kodu

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

Dzięki za przyjrzenie się i pomoc!

Odpowiedzi

1 DmitryBychenko Dec 14 2020 at 13:18

Dobrze [Sorted]Setmoże zawierać tylko różne elementy; tj. Setnie może mieć dwóch równych elementów. Porównujesz Countpozycje (traktujesz je jako równe) pod względem : jeśli dwa przedmioty mają takie same Count, są uważane za równe. W twoim kodzie

  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

masz one.Count == two.Count == 1to dlatego onei tworówne dla counterposortowanego zestawu. Podczas dodawania elementów druga (czyli two) jest ignorowana:

  counter.Add(one);
  counter.Add(two); // Ignored: there's already an item (one) with the same Count
  counter.Add(three);

Jeśli chcesz mieć oddzielne kryteria (jedno dla, Equalsa drugie dla zamówienia), możesz wypróbować stare dobre, HashSetktóre możesz przedstawić zgodnie z zamówieniem z pomocą 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);