"True" OO design - sorting objects

I have 2 classes OrderInfo and OrderManager. The OrderInfo class is the model of an Order and the OrderManager does all the work on the OrderInfo such as Insert, Update, Delete, Sort etc.

I’m trying to implement sorting and have the following code in the OrderManager class:

public static Collection<OrderInfo> Sort(string sortExpression, string sortDirection)

{

GenericComparer comparer = new GenericComparer();

comparer.SortExpression = sortExpression;

comparer.SortDirection = sortDirection;

call Compare method

//Return a sorted generic collection of Orders.

return orders;

}

private sealed class GenericComparer : IComparer<OrderInfo>

{

#region Internal member variables and properties

private string _sortExpression = string.Empty;

public string SortExpression

{

get { return _sortExpression; }

set { _sortExpression = value; }

}

private string _sortDirection = "Ascending";

public string SortDirection

{

get { return _sortDirection; }

set { _sortDirection = value; }

}

#endregion

public int Compare(OrderInfo o, OrderInfo oo)

{

OrderInfo order = o;

OrderInfo otherOrder = oo;

if (this.SortDirection.Equals("Ascending"))

{

return order. .CompareTo(otherOrder. );

}

else

{

return otherOrder. .CompareTo(order. );

}

}

}

First of all if this is a BS approach let me know. Otherwise here is the error I’m getting:

Error 1 'Model.OrderInfo' does not implement interface member 'System.IComparable<Model.OrderInfo>.CompareTo(Model.OrderInfo)' D:\Projects\ShareYourLoss\Model\OrderInfo.cs 11 18 Model

I don’t want to implement IComparable or ICompare in the OrderInfo. I want my OrderManager to do all the work and I want the GenericComparer to be flexible enough to sort any column passed in from a GridView for example. So it would be order. + SortExpression. So that I can sort by OrderID, ShipDate etc. depending which column is clicked. The code is not finished but I’m in over my head and don’t know how to finish it.

An even nicer solution would be to have a separate comparer class that is generic enough and could sort any collection of objects OrderInfo, CustomerInfo, ProductInfo etc. but I have no idea how to accomplish that.

Would anybody be kind enough and help newbie out

Thanks,



Answer this question

"True" OO design - sorting objects

  • dukesta3

    I was just thinking if I already have an object in memory it would be faster to sort the existing object rather than go back to the database. It would be easier for me to just pass the sortExpression and sortDirection to a Stored Procedure and return the data but I am trying to avoid another trip to the database.

    By the way thank you for the code I will try and use it tomorrow and see if I can get it to work.


  • reno_rens2002

    Well, the error seems to be there bcause you specified the interface IComparable<OrderInfo> on the class OrderInfo, but did not implement it.

    Seems like you want to use that interface, too, as you call order.CompareTo(). But does that really make sense I mean, did you implement some kind of meaningful comparison inside the order If you want to sort by a specific property (column) of the order, you have to compare the values of that property and not the order itself.

    Here is an example of a "generic" comparer that can work on almost any kind of object list:

    public class ObjectComparer<T> : IComparer<T> where T : class
    {
    private PropertyDescriptor propertyDescriptor;
    private ListSortDirection direction;

    public ObjectComparer(string propertyName, ListSortDirection direction)
    {
    this.propertyDescriptor = TypeDescriptor.GetProperties(typeof(T))[propertyName];
    this.direction = direction;
    }

    public ObjectComparer(PropertyDescriptor propertyDescriptor, ListSortDirection direction)
    {
    this.propertyDescriptor = propertyDescriptor;
    this.direction = direction;
    }

    #region IComparer<object> Members

    public int Compare(T x, T y)
    {
    object xVal = this.propertyDescriptor.GetValue(x);
    object yVal = this.propertyDescriptor.GetValue(y);

    int dir = direction == ListSortDirection.Descending -1 : 1;

    if (xVal is IComparable)
    {
    IComparable comparable = xVal as IComparable;
    int val = (dir * comparable.CompareTo(yVal));
    return val;
    }
    return 0;
    }
    #endregion
    }

    If you have a list like List<MyClass> myList that has a property named "Name" you can sort it like that:
    myList.Sort(new ObjectComparer<MyClass>("Name", ListDirection.Ascending));

    This comparer requires that the property values are comparable, if you expect them not to be, you have to put some other meaningful comparison in the method. Probably you want to have a far more sophistacted comparision as I see you pass in an expression as a string of some kind, e.g. sorting by multiple properties in a specific order.

    Although this comparer defeats somhow the purpose of generics to speed up the execution because getting the value through the PropertyDescriptor is less efficient.


  • D Davidson

    I like OO design as much as the next guy (maybe even more so), but shouldn't you let the thing in your system most adept at sorting (i.e. the backend database that is properly indexed) do it
  • John Turley

    There are many ways to skin a cat ;)

    I was just suggesting a solution for what he wants to do, but on the other hand... even a database query can be expensive, e.g. because of network speed, amount of data that needs to be transfered, the schema and so forth. But I agree, one should not chose a tool because one likes it if it is not suitable for the work that has to be done.


  • "True" OO design - sorting objects