Is there a sorted collection type in .NET?

前端 未结 7 1601
夕颜
夕颜 2020-12-01 08:19

I\'m looking for a container that keeps all its items in order. I looked at SortedList, but that requires a separate key, and does not allow duplicate keys. I could also j

相关标签:
7条回答
  • 2020-12-01 08:27

    Here's an old trick I used way back in VB6 to sort things alphabetically: Use a System.Windows.Forms ListBox object, and set its "Sorted" property to true. In C#, you can insert any object into the listbox, and it will sort the object alphabetically by its ToString() value:

    for a class module:


    using System.Windows.Forms;

        static void Main(string[] args)
        {
            ListBox sortedList = new ListBox();
            sortedList.Sorted = true;
    
            sortedList.Items.Add("foo");
            sortedList.Items.Add("bar");
            sortedList.Items.Add(true);
            sortedList.Items.Add(432); 
    
            foreach (object o in sortedList.Items)
            {
                Console.WriteLine(o);
            }
    
            Console.ReadKey();
        }
    

    This will display:

    432
    bar
    foo
    True

    0 讨论(0)
  • 2020-12-01 08:29

    I would extend your own list class that, as you mentioned, simply sorts after every insert. Since your inserts are infrequent the performance hit would be minimal, and sorting a nearly sorted list is quick, in any case. Extend the Generic List and override the Add method to sort immediately. If performance becomes an issue you can insert in place to save some time. Furthermore you can queue up your inserts to do a single traversal insertion for all the values you want to insert.

    0 讨论(0)
  • 2020-12-01 08:31

    You might want to take a look at the Wintellect Power Collections. It is available on CodePlex and contains quite a few collections that are very helpful. The OrderedBag collection in the project is exactly what you are looking for. It essentially uses a red-black tree to provide a pretty efficient sort.

    0 讨论(0)
  • 2020-12-01 08:35

    Just to make EBarr's comment as answer, there is SortedSet<T> since .NET 4.0. Of course it is a set, which means you cannot have duplicates.

    0 讨论(0)
  • 2020-12-01 08:41

    If you just want to stick with the standard collections then the Sort(IComparer<>) function of the List<> class is one that often gets ignored. All you need to do is create a suitable Comparer<> for your objects. For example:

    public class PositionDateComparer : IComparer<VehiclePosition>
    {
        public int Compare(VehiclePosition x, VehiclePosition y)
        {
            if (x.DateTime == DateTime.MinValue)
            {
                if (y.DateTime == DateTime.MinValue)
                {
                    // If x is null and y is null, they're
                    // equal. 
                    return 0;
                }
    
                // If x is null and y is not null, y
                // is greater. 
                return -1;
            }
    
            // If x is not null...
            //
            if (y.DateTime == DateTime.MinValue)
            // ...and y is null, x is greater.
            {
                return 1;
            }
    
            // ...and y is not null, compare the dates
            //
            if (x.DateTime == y.DateTime)
            {
                // x and y are equal
                return 0;
            }
    
            if (x.DateTime > y.DateTime)
            {
                // x is greater
                return 1;
            }
    
            // y is greater
            return -1;
        }
    }
    

    Then just perform a vehiclePositionsList.Sort(new PositionDateComparer()) whenever you want to sort the list before accessing it. I realise that this might not be as simple as a container which automatically sorts every time you add a new object, but for many (like me!) this might be enough to do the job successfully without requiring any additional libraries.

    0 讨论(0)
  • 2020-12-01 08:41

    If the key is also an attribute of the object, you might try the System.Collections.ObjectModel.KeyedCollection<TKey, TItem>. It's an abstract class, but if your key is just a property of the item then it's real simple to derive from.

    0 讨论(0)
提交回复
热议问题