Sortable Custom Collections

  • Thread starter Thread starter David Young
  • Start date Start date
D

David Young

First of all Yes, I know it's possible and have implemented it before.
Using c#, Ive created several base class objects, many of which can belong
to collections. I've written the collection classes, i've inherited from
CollectionsBase and have written the necessary methods to make it
enumerable. Now it's on to sorting. In the collection class, I can write
class for the sorting (IComparer)


private class AscendingNameSorter
{
public int Compare(object x, object y)
{
BaseClass p1 = (BaseClass)x;
IComparable ic1 = (IComparable)p1.Name;

BaseClass p2 = (BaseClass)y;
IComparable ic2 = (IComparable)p2.Name;

return ic1.CompareTo(ic2);
}
}

And then sort using the following:

public void SortByName()
{
IComparer NameSorter = new AscendingNameSorter();
InnerList.Sort(NameSorter);
}

Now, that's fine and dandy if I want to write a sorter and a method for
EVERY property that I want to sort by. But that just wont work for some
classes that have 20+ properties, and they want the option to sort by any
property. What I need it to be able to write a default sorter that I can
send the property name to as a string, and then [using reflection?] have the
sorter (IComparer) class sort on the appropriate property. Is that
possible? Anyone got any ideas of how I can do that?

Dave
 
If you want flexibility (at the cost of dev time and performance), then you
can use something like this:

public class MemberComparer : IComparer
{
string _member;
public MemberComparer(string member)
{
_member = member;
}
public int Compare(object x, object y)
{
object lhs = System.Web.UI.DataBinder.Eval(x, _member);
object rhs = y;
if (x.GetType() == y.GetType())
{
rhs = System.Web.UI.DataBinder.Eval(y, _member);
}
return ((IComparable)lhs).CompareTo(rhs);
}
}

Array.Sort(myArray, new MemberComparer("SomeProperty"));

-Brock
DevelopMentor
http://staff.develop.com/ballen
 
If all properties of your BaseClass implement
IComparable, you can use the following code:

public class Collection : CollectionBase
{
public BaseClass this[int index]
{
...
}

...

public void Sort(string key)
{
InnerList.Sort(new BaseClassComparer(key));
}

private class BaseClassComparer : IComparer
{
public BaseClassComparer(string key)
{
propInfo = typeof(BaseClass).GetProperty(key);
if (propInfo == null)
throw new ArgumentException("key",
"The property does not exist.");
}

PropertyInfo propInfo;

public int Compare(object x, object y)
{
IComparable a = (IComparable)propInfo.GetValue(x);
return a.CompareTo(propInfo.GetValue(y));
}
}
}

Mark Rockmann
 
Back
Top