0

I have a SortedList in my code. I fill inside it key value pairs. When I add an item to SortedList it sorts automatically by key. But i need to sort it by value. Because the values are visible texts in a combobox. They must be alphabetically sorted. I decided to write a class and inherit from SortedList class and override the Add method.

But when I looked at the code of Microsoft's SortedList class, I see there is an Insert method and it makes the sorting and unfortunately it is private so I cannot override it. Can you help me about this?

Note: I cant use ArrayList or Dictionary or something else. I cannot manage all code in our project. I have to return 'SortedList' or 'MySortedList' derived from SortedList

nawfal
  • 70,104
  • 56
  • 326
  • 368
Hakan Kara
  • 433
  • 1
  • 6
  • 16
  • Do you have any requirements on what the keys must be? If not, why not just add your text as both the key and the value? `sortedList.Add(text,text)` – Douglas Nov 16 '12 at 10:23
  • Yes the first parameter has to be key and the second one has to be value. It depends on other classes in our project – Hakan Kara Nov 16 '12 at 11:28
  • possible duplicate of [C# Sorted List by Value with Object](http://stackoverflow.com/questions/16649481/c-sharp-sorted-list-by-value-with-object) – nawfal May 22 '14 at 05:38
  • `Insert` method ought to be private because it makes no sense to insert something at a particular position in a collection that has its own order (sorted order). Better implement a custom collection that holds both a dictionary (for keyed access) and a sortable collection (like List) to remember order. You will get a sample implementation in the question I linked above. Goodness me, dont use reflection for this, that too on code you dont own. – nawfal May 22 '14 at 07:21

1 Answers1

2

My first suggestion was to use a custom comparer but his didn't solve the problem. I therefore investigated SortedList implementaion more detailed and replaced my original post with the following suggestion:

Overriding the Add method and invoke the private Insert using reflection should do the trick

private MySortedList()
{
}

public override void Add(object key, object value)
{
    if (key == null || value == null)
    {
        //throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
        throw new ArgumentNullException(); // build your own exception, Environment.GetResourceString is not accessible here
    }

    var valuesArray = new object[Values.Count];
    Values.CopyTo(valuesArray , 0);

    int index = Array.BinarySearch(valuesArray, 0, valuesArray.Length, value, _comparer);
    if (index >= 0)
    {
        //throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate__", new object[] { this.GetKey(index), key }));
        throw new ArgumentNullException(); // build your own exception, Environment.GetResourceString is not accessible here
    }

    MethodInfo m = typeof(SortedList).GetMethod("Insert", BindingFlags.NonPublic | BindingFlags.Instance);
    m.Invoke(this, new object[] {~index, key, value});
}
Lukas Winzenried
  • 1,919
  • 1
  • 14
  • 22