C#のソートされたセットはカスタムオブジェクトでどのように機能しますか?[複製]

Dec 14 2020

カスタムオブジェクトのc#で並べ替えられたセットを試してみましたが、何らかの理由で、並べ替えられたセットがオブジェクトの参照を使用してデータを格納していないようです。

次のコードスニペットでは、カスタムIComparerを使用して、カスタムクラスのCountsプロパティに依存しています。しかし、何らかの理由で、これは追加機能に影響を与えるようです。また、counter.Add(two)行は、参照が異なり、2つのプロパティの値が異なる場合でも、セットに追加を行いません。

私は何かが足りないのですか?SortedSetsがC#でどのように機能するかについて何か問題がありますか?

コードスニペット

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

見てくれてありがとう!

回答

1 DmitryBychenko Dec 14 2020 at 13:18

ウェルに[Sorted]Setは、個別のアイテムのみを含めることができます。つまり、Set2つ以上の等しいアイテムを持つことはできません。アイテムを比較します(それらを等しいものとして扱います)Count:2つのアイテムが同じである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理由ですonetwoしているに等しいのためのcounterソートセット。アイテムを追加すると、2番目(つまりtwo)は無視されます。

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

あなたがしたい場合分けの基準(のための1つ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);