4

Possible Duplicate:
Sorting an IList in C#

I have the following method and I need to sort the iList object that is being passed to it (inside this method). I have tried linq but since it's an interface I'm getting errors.

Thanks in advance

private void AddListToTree(ComponentArt.Web.UI.TreeView treeView, IList list)
{
//NEED TO SORT THE LIST HERE
}

Please note that my type is Dynamic.

I think I should create a temporary collection, populate if from my instance of IList, sort it, get appropriate instance of the object supporting IList and use it instead of my non-sorted instance of IList which I should leave intact. So I tried getting the type like following:

Type[] listTypes = list.GetType().GetGenericArguments();
Type listType = null;
if (listTypes.Length > 0)
{
listType = listTypes[0];
}

But I cannot create a new List with this type

Community
  • 1
  • 1
Sev
  • 761
  • 4
  • 16
  • 29

6 Answers6

8

You should use the generic form of IList to be able to use the LINQ extension methods:

private void AddListToTree<T>(ComponentArt.Web.UI.TreeView treeView,
                              IList<T> list)
{
    var orderedList = list.OrderBy(t => t);
    // ...
}

If you can't modify the method's signature but you know the type of the objects in the IList, you can use Cast:

private void AddListToTree(ComponentArt.Web.UI.TreeView treeView,
                           IList list)
{
    var orderedList = list.Cast<SomeType>().OrderBy(x => x);
    // ...
}
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • I'm cannot alter the method type. Any other way beside LINQ to sort the List interface object? – Sev Nov 28 '11 at 18:42
  • +1 Using IList provides access to the generic methods such as orderby(). – Sogger Nov 28 '11 at 18:47
  • @SevAbedi: See update. Does that help? Requires you know the type in advance though. – Mark Byers Nov 28 '11 at 18:48
  • Can I somehow get the type? Cuz they can be type of 3 different classes – Sev Nov 28 '11 at 18:51
  • 3
    @SevAbedi, back up. What's the reason you can't change the signature? Do the three classes share a same base class or interface? Would your given `IList` be mixed, containing objects of different types at the same time? It's difficult to craft a solution unless provide a bit more detail to the problem. – Anthony Pegram Nov 28 '11 at 18:54
  • I tried :
    Type[] listTypes = list.GetType().GetGenericArguments();
        Type listType = null;
        if (listTypes.Length > 0)
        {
        listType = listTypes[0];
        }
        var orderedList = list.Cast().OrderBy(x => x);
    
    
    -------
    But the type I extracted from the list wasn't available to cast the list with. Says the type or namespace cannot be found
    
                var orderedList = list.Cast().OrderBy(x => x);
    – Sev Nov 28 '11 at 19:03
  • 1
    No, that approach will not work. `Cast` does not expect a `Type` object, that is to say, it's not expecting metadata about the type as in `.Cast`, it's expecting the `T` directly, as in `.Cast`. – Anthony Pegram Nov 28 '11 at 19:05
  • So any other way to sort this list? – Sev Nov 28 '11 at 19:09
  • If it was a List versus an IList you can run List.Sort(delegate(a, b){}); and do your sort inside there – Ryan Ternier Nov 29 '11 at 00:06
1

You could use Cast<T>() to change it to IList<T> then use OrderBy():

private void AddListToTree<T>(ComponentArt.Web.UI.TreeView treeView, IList list)
{
    var ordered = list.Cast<T>().OrderBy(e => e);
}

Somewhere you will need to know the type to do the sorting.

JohnD
  • 14,327
  • 4
  • 40
  • 53
1

For LINQ: Duplicate question as : Sorting an IList in C#

You can also use extension methods to add the Sort command to IList: Why is there no Sort for IList<T>?!?! (edited)'

You can do the following (WhicH I don't endorse, but it's still doable)

IList list;
ArrayList al = new ArrayList(list);
al.Sort();

You can also utilize IComparable: http://devpinoy.org/blogs/keithrull/archive/2007/03/23/sorting-a-generic-list-of-object-in-c-using-icomparable-and-anonymous-delegates.aspx

or

http://foxsys.blogspot.com/2007/06/how-to-sort-generic-ilist.html

Community
  • 1
  • 1
Ryan Ternier
  • 8,714
  • 4
  • 46
  • 69
  • I tried the ArrayList approach but I'm getting the following error: Failed to compare two elements in the array. – Sev Nov 28 '11 at 18:49
  • Note that using the constructor taking IList will cause Sort to sort the new ArrayList (which contains a copy of the original IList contents) and not the original IList. – Dan Bryant Nov 28 '11 at 18:50
1

One way (note that you must specify the item type in the from clause):

IList list = new ArrayList();
list.Add("z");
list.Add("a");
list.Add("c");

IEnumerable<string> ordered =
    from string item in list
    orderby item
    select item;

foreach (var s in ordered)
{
    Console.WriteLine(s);
}

Prints:

a
c
z

Note: Based on your later comment of

they can be type of 3 different classes

this will not work. I would seriously consider refactoring the calling code.

If you have no ability to edit the types, and if the types should not be intermixed in the sorted list, here's an option:

var one = list.OfType<TypeOne>().OrderBy(x => x.Id);
var two = list.OfType<TypeTwo>().OrderBy(x => x.Name);
var three = list.OfType<TypeThree>().OrderBy(x => x.Nom);

var result =
    one.Cast<object>()
    .Concat(two.Cast<object>())
    .Concat(three.Cast<object>());
TrueWill
  • 25,132
  • 10
  • 101
  • 150
0

One option is to create an ArrayList adapter around the IList using ArrayList.Adapter, then sort it using ArrayList.Sort. This is if you need an in-place sorting operation that mutates the array contents, rather than returning a sorted enumeration.

Dan Bryant
  • 27,329
  • 4
  • 56
  • 102
0

If you can't change the signature or use LINQ, use an extension method or custom method.

Examples given in the duplicate question listed by @Ryan Ternier:

LINQ: Duplicate question as : Sorting an IList in C#

Community
  • 1
  • 1
Sogger
  • 15,962
  • 6
  • 43
  • 40
  • Ryan just posted a more informative answer so see it for more info, I was just quoting his comment on the question. – Sogger Nov 28 '11 at 18:51