tags:

views:

410

answers:

4

Here's my setup.

public class ItemList : List<Item>
{
  public void Load() {...}
  public void Save() {...}
}

Load reads from an XML file to populate the ItemList

I then attempt to order the item list by a Priority. This is an int? For the test purposes however all the items have a different value.

ItemList itemList = new ItemList();
itemList.Load();

ItemList newItemList = itemList
                        .OrderBy(item => item.Priority) as ItemList;

return newItemList;

In the above newItemList is always null. itemList has a Count of 7. I've triple checked and all the items in the itemList instance have a priority set.

What am I doing wrong?

I've also tried...

ItemList newItemList = itemList
                        .OrderBy(item => item.Priority)
                        .ToList() as ItemList;

Nothing seems to be working.

Thanks in advance!

+7  A: 

The problem is that OrderBy doesn't return an ItemList, it returns an IOrderedEnumerable, and ToList() doesn't return an ItemList, it returns an List. Either way, you're trying to cast both to an ItemList, which they aren't, so you get null.

ItemList someList = (new ItemList {new Item(2), new Item(1), new Item(3)});

//this returns an IOrderedEnumerable<Item>
var result = someList.OrderBy(i => i.Priority); 

//this returns a List<Item>
var otherResult = someList.ToList();
Joseph
Thank you for the explanation now I just have to figure out how to use OrderBy and end up with an ItemList. I don't want to use Sort because I don't want to build CompareTo methods for everything.When I try and use the solution below that uses Sort CompareTo is not a valid method off Priority, and Priority is an int?
Altonymous
Got it I think!itemList.Sort((x, y) => x.Priority.HasValue.CompareTo(y.Priority));
Altonymous
Not the answer.. wasn't thinking it through... When I use HasValue it's trying to compare the result of HasValue, which is a bool, to the priority.Still working on it!
Altonymous
A: 

I think your issue is the " as ItemList".

rally25rs
That won't work either since the result cannot be cast to an ItemList.
Per Erik Stendahl
Good point. I wasnt taking into account the need to upcast the list back to the ItemList type.
rally25rs
A: 

The LINQ operators doesn't work in-place on your newItemList object. They create and return new objects. If you want to do in-place sorting you should use the Sort() method of List<>.

Per Erik Stendahl
+2  A: 

Neither OrderBy or ToList returns an ItemList, so the casting returns null, as Joseph pointed out.

As you are inheriting from the List<T> class, you can just use the Sort method to sort it:

ItemList itemList = new ItemList();
itemList.Load();
itemList.Sort((x, y) => x.Priority.CompareTo(y.Priority));
return itemList;
Guffa
I'm trying to avoid using Sort, because unless I'm mistaken, which I frequently am, it requires building out CompareTo methods for everything I want to sort on.
Altonymous
BTW, When I try and use this solution, CompareTo is not a valid method off Priority. Priority is an int?
Altonymous
Got it I think!itemList.Sort((x, y) => x.Priority.HasValue.CompareTo(y.Priority));
Altonymous
Not the answer.. wasn't thinking it through... When I use HasValue it's trying to compare the result of HasValue, which is a bool, to the priority.Still working on it!
Altonymous
You need a method for comparison with Sort, and you need a method for property extraction with OrderBy, so there isn't really any difference in effort. To compare nullables use: itemList.Sort((x, y) => Nullable<int>.Compare(x.Priority, y.Priority));
Guffa
That code doesn't work either but I'm going to give you answer credit for trying. There is no Compare off Nullable<int>.Making this note so others will know in advance before trying it.
Altonymous
ItemList.Sort((x, y) => Nullable.Compare<Int32>(x.Priority, y.Priority));
Altonymous
Yes, you are right. It's of course the method that you apply the generic type to, not the Nullable type. :P
Guffa