How to sort an iList (With linq or without) [duplicate]
Asked Answered
F

6

5

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

Fleet answered 28/11, 2011 at 18:36 Comment(0)
T
9

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);
    // ...
}
Telepathist answered 28/11, 2011 at 18:38 Comment(9)
I'm cannot alter the method type. Any other way beside LINQ to sort the List interface object?Fleet
+1 Using IList<T> provides access to the generic methods such as orderby().Jocko
@SevAbedi: See update. Does that help? Requires you know the type in advance though.Telepathist
Can I somehow get the type? Cuz they can be type of 3 different classesFleet
@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.Townsend
I tried : <pre><code>Type[] listTypes = list.GetType().GetGenericArguments(); Type listType = null; if (listTypes.Length > 0) { listType = listTypes[0]; } var orderedList = list.Cast<listType>().OrderBy(x => x); <pre/><code/> ------- 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<listType>().OrderBy(x => x);Fleet
No, that approach will not work. Cast<T> does not expect a Type object, that is to say, it's not expecting metadata about the type as in .Cast<typeof(int)>, it's expecting the T directly, as in .Cast<int>.Townsend
So any other way to sort this list?Fleet
If it was a List versus an IList you can run List<T>.Sort(delegate(a, b){}); and do your sort inside thereLupulin
E
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.

Elena answered 28/11, 2011 at 18:39 Comment(3)
It's an iList not a listFleet
I dont have the type (T)Fleet
Don't you need to know the type in order to sort... ?Elena
L
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

Lupulin answered 28/11, 2011 at 18:41 Comment(2)
I tried the ArrayList approach but I'm getting the following error: Failed to compare two elements in the array.Fleet
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.Chowchow
P
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>());
Petaliferous answered 28/11, 2011 at 18:55 Comment(0)
C
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.

Chowchow answered 28/11, 2011 at 18:49 Comment(0)
J
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#

Jocko answered 28/11, 2011 at 18:49 Comment(1)
Ryan just posted a more informative answer so see it for more info, I was just quoting his comment on the question.Jocko

© 2022 - 2024 — McMap. All rights reserved.