0

I have a list in a base class. Each derived class has its unique needs for sorting the common list in base-class. For this purpose I would like to create a method in base-class which gets a string. The string contains a custom "OrderBy" query.

Instead of:

protected void SortBaseClassList(string orderByQueryString)
{
     List<MyBaseClass> sortedList = BaseClassList.OrderByDescending(x => x.GetTop)
                                                 .ThenBy(x => x.GetLeft)
                                                 .ToList<MyBaseClass>();
}

I would like to use:

 protected void SortBaseClassList(string orderByQueryString)
    {
      List<MyBaseClass> sortedList =   
           BaseClassList. + orderByQueryString + .ToList<MyBaseClass>();
    }  

Is this possible? If so, how can I do it?

Adriano Carneiro
  • 57,693
  • 12
  • 90
  • 123
user3165438
  • 2,631
  • 7
  • 34
  • 54
  • Where does the query string come from? When you say it is *custom*, do you mean *custom* as in input/configurable by the user, or *custom* as in statically depending on the class being sorted? – O. R. Mapper Mar 27 '14 at 12:58
  • 1
    Can't you just use dictionary with key as queryString and value as lambda for ordering and then in your method find element with that key and use lambda ? – kosnkov Mar 27 '14 at 12:59
  • @O.R.Mapper Custom is the unique custom orderBy query of derived classes. – user3165438 Mar 27 '14 at 13:00
  • Your code relies too heavily on strings. On this way there's a great danger of introducing nasty bugs or unmaintainable code. – Tim Schmelter Mar 27 '14 at 13:01
  • @user3165438: So, each derived class has its own "orderBy query" that is hard-coded for that class? – O. R. Mapper Mar 27 '14 at 13:01
  • @TimSchmelter What is your suggestion? – user3165438 Mar 27 '14 at 13:01
  • I think you shouldnt pass a string, but a comparer: http://stackoverflow.com/questions/985657/use-own-icomparert-with-linq-orderby – thumbmunkeys Mar 27 '14 at 13:02
  • @O.R.Mapper Exactly. Not worried about the "hard coded" fact.... – user3165438 Mar 27 '14 at 13:02
  • I think you're missing the point. The question you're asking has nothing to do with inheritance, since you're method would allow you to do any sorting on any class. Instead use some kind of private list member and public IEnumerable accessor. – Tarec Mar 27 '14 at 13:03
  • Are there only elements of the same (derived) type in an instance of `List`? – Markus Mar 27 '14 at 13:03
  • @user3165438: i can't suggst anything because i have no background informations. What is `orderByQueryString` for instance? – Tim Schmelter Mar 27 '14 at 13:04
  • 1
    Could you please fix your question's title? It makes no sense at all. – Ondrej Tucny Mar 27 '14 at 13:04

1 Answers1

1

You seem to require a particular set of ordering rules for every subclass of MyBaseClass. That is exactly what polymorphism in class hierarchies is there for, and you can use it by implementing the IComparable<T> interface.

Add an abstract implementation to your base class:

public abstract class MyBaseClass : IComparable<MyBaseClass>
{
    // ...

    public abstract int CompareTo(MyBaseClass other);
}

Then, in each of your subclasses, override CompareTo in an appropriate way to apply the subclass-specific ordering. Here is an exemplary subclass:

public class MySubClass : MyBaseClass
{
    // ...

    public int SomeValue { get; set; }

    public override int CompareTo(MyBaseClass other)
    {
        if (other == null) {
            // every instance comes after null, cf. docs
            return 1;
        }

        var typedOther = other as MyBaseClass;
        if (typedOther != null) {
            // other instance of same type; compare by custom sorting criteria
            return this.SomeValue.CompareTo(typedOther.SomeValue);
        } else {
            // other instance of different type; make sure different types are always sorted in the same order
            return GetType().FullName.CompareTo(other.GetType().FullName);
        }
    }
}

A side-effect of this is that you do not need the LINQ OrderBy method any more; you can now directly invoke Sort on the list (without specifying anything additional, such as a comparer) and sort in-place rather than creating a new list:

BaseClassList.Sort();
O. R. Mapper
  • 20,083
  • 9
  • 69
  • 114