Sorting Generics with IComparer<T>
I'm a huge fan of Generics.
I've replaced all of my code generated custom colletion classes with List<T>. But along with my simple implementation of CollectionBase I built in some custom sorting for my objects.
I know the correct way would be to implement IComparer with all my objects and sort that way, but the truth is I very rarely sort anything (only when displaying data t the user). I like just running my CodeSmith template against all 25 of my tables to generate some nice objects that take care of all the C.R.U.D. functions, along with the stored procs to make them work.
Meanwhile, back at the ranch, I need to sort my List<T>'s by a particular property value. Here was my solution:
Now you can sort a generic list of custom objects like this:
I understand that this isn't the most efficient way of sorting (using reflection) but like I said, I don't use this method often, and it works perfectly for my situation.
NOTE: Notice line 17 and 21 use GetType() rather than typeof(T) in case the properties aren't provided by T itself, but by a class derived from T.
Thanks to a suggestion from Jon Skeet
This implementation was inspired by my problem and the following post: http://www.dotnetjunkies.com/Tutorial/5091F698-EF8B-436B-A345-AFBEF18CE229.dcik
I've replaced all of my code generated custom colletion classes with List<T>. But along with my simple implementation of CollectionBase I built in some custom sorting for my objects.
I know the correct way would be to implement IComparer with all my objects and sort that way, but the truth is I very rarely sort anything (only when displaying data t the user). I like just running my CodeSmith template against all 25 of my tables to generate some nice objects that take care of all the C.R.U.D. functions, along with the stored procs to make them work.
Meanwhile, back at the ranch, I need to sort my List<T>'s by a particular property value. Here was my solution:
1: public enum GenericComparerSortDirection { Asc, Desc }
2:
3: public class GenericComparer<T> : IComparer<T>
4: {
5: private string propertyName;
6: private GenericComparerSortDirection theDirection;
7:
8: public GenericComparer(string propertyName, GenericComparerSortDirection eSortDirection)
9: {
10: this.propertyName = propertyName;
11: this.theDirection = eSortDirection;
12: }
13:
14: public int Compare(T x, T y)
15: {
16: // gets the value of the x property
17: PropertyInfo property = x.GetType().GetProperty(propertyName);
18: object valueOfX = property.GetValue(x, null);
19:
20: // gets the value of the y property
21: property = y.GetType().GetProperty(propertyName);
22: object valueOfY = property.GetValue(y, null);
23:
24: // now make the comparsion
25: if (this.theDirection == GenericComparerSortDirection.Asc)
26: return ((IComparable)valueOfX).CompareTo(valueOfY);
27: else
28: return ((IComparable)valueOfY).CompareTo(valueOfX);
29: }
30: }
Now you can sort a generic list of custom objects like this:
1: List<MyClass> lstSorted = getABunchOfObjects();
2: lstSorted.Sort(new GenericComparer<MyClass>("PropertyName", GenericComparerSortDirection.Asc));
I understand that this isn't the most efficient way of sorting (using reflection) but like I said, I don't use this method often, and it works perfectly for my situation.
NOTE: Notice line 17 and 21 use GetType() rather than typeof(T) in case the properties aren't provided by T itself, but by a class derived from T.
Thanks to a suggestion from Jon Skeet
This implementation was inspired by my problem and the following post: http://www.dotnetjunkies.com/Tutorial/5091F698-EF8B-436B-A345-AFBEF18CE229.dcik
0 Comments:
Post a Comment
<< Home