tags:

views:

193

answers:

2

I have List I want to sort Desc by Priority, which is int and can be anything from 0 to 100.
I use GenericComparer, which allows to set the SortDirection and sortExpression. Works well for any string property, like a Name (which is property of ProductLowDetail). However for Priority it behaves strange. It does sort, but it changes the direction of sorting (from Desc to Asc and then from Asc to Desc and that is repeated) for each reload of List (simple F5 in browser).
I store List in session and below id code how I call it.

productList.Sort(new GenericComparer<ProductLowDetail>("DisplayPriority", SortDirection.Descending));

Part of comparer implementation:

public int Compare(T x, T y){
   PropertyInfo propertyInfo = typeof (T).GetProperty(_sortExpression);    
   IComparable obj1 = (IComparable) propertyInfo.GetValue(x, null);    
   IComparable obj2 = (IComparable) propertyInfo.GetValue(y, null);     

   if (SortDirection == SortDirection.Ascending){   
      return obj1.CompareTo(obj2);   
   }
   return obj2.CompareTo(obj1);   
}

Has someone get into this problem too? thanks for any suggestion. X.

+1  A: 

That does sound odd. Please provide a short but complete program (ideally a short console app) which demonstrates the behaviour.

One thought: do your products definitely have different display priorities? List.Sort is an unstable sort, meaning that equal items can be reordered. If your products all have the same display priority, that would explain the behaviour...

Jon Skeet
Sure there are some Products that have the same priority, like equal to 0 or 1. SO it is multyple occurence. But they differ along whole list.
Xabatcha
In that case we'll need to see a failing test example.
Jon Skeet
Yes you were right about is Unstable. It just keep switching order for products with the same priority. So I made it simpler for Sorter. I have made custom sorter and join priority together with id, which sorted out the problem. Th.
Xabatcha
Would u like still see the whole code?
Xabatcha
No, that's fine :)
Jon Skeet
A: 

As I understand, you rolled out you own version of GenericComparer. System.Collections.Generic has an internal one for their use.

Haven’t seen the code that calls Compare I can only suspect that your problem may have something to do with your checking of SortDirection.Ascending inside Compare.

Compare should return the same result regardless of the sort order. It should be the callers task to sort based on that information.

Take of the checking of SortDirection as done below:


public int Compare(T x, T y) {
    PropertyInfo propertyInfo = typeof(T).GetProperty(_sortExpression);
    IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null);
    IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null);
    return obj1.CompareTo(obj2);
}

If that does not work for you, please post more of the source code (such as Compare's caller) so we can help you.

Alfred Myers
Compare's caller will be List.Sort. It's entirely reasonable to have a "descending comparer" and an "ascending comparer". List.Sort will always sort in ascending order according to the comparer itself.
Jon Skeet
I took away the checking of the SortDirection and it does the same, still switching the direction.
Xabatcha