xandi1987
xandi1987

Reputation: 519

Generic order method by specific property

I am quite new in generic programming and have a question:

I am trying to order a list by specific properties which should be defined as parameter. Please look at the code for better understanding what I want:

public static IEnumerable<T> SortEmployeesFor<T>(
    IEnumerable<T> list,
    property1,
    property2, 
    OrderOptions options)
{
    switch (options)
    {
        case OrderOptions.1:
            return list.OrderBy(x => property1).ThenBy(x => property2);

        case OrderOptions.2:
            return list.OrderBy(x => property2).ThenBy(x => x.property1);

        ...
    }

    return list;
}

Is there any option to perform this?


P.S. It's my first post, if I did something wrong, please understand and let me know.

Upvotes: 1

Views: 135

Answers (5)

Jodrell
Jodrell

Reputation: 35726

When you look it up on MSDN you note that OrderBy, and ThenBy take a Func<TSource, TKey> as the key selector parameter.

So you could write some generic extension like this.

public static IEnumerable<T> SortWithOptions<T, TKey1, TKey2>(
    this IEnumerable<T> source,
    Func<T, TKey1> selector1,
    Func<T, TKey2> selector2,
    OrderOptions options)
{
    switch (options)
    {
        case OrderOptions.One:
             return source.OrderBy(selector1).ThenBy(selector2);

        case OrderOptions.Two:
             return source.OrderBy(selector2).ThenBy(selector1);
    }
}

Then, if you want a non-generic implementation for employees you could write,

public static IEnumerable<Employee> SortEmployees(
    IEnumerable<Employee> unsorted,
    OrderOptions options)
{
    return unsorted.SortWithOptions(
        e => e.Cost,
        e => e.Ability,
        options);
}

Upvotes: 0

Prasad Kanaparthi
Prasad Kanaparthi

Reputation: 6563

Try this,

list.OrderBy("SomeProperty DESC, SomeOtherProperty ASC");

list.OrderBy("SomeProperty");
list.OrderBy("SomeProperty DESC");
list.OrderBy("SomeProperty DESC, SomeOtherProperty");
list.OrderBy("SomeSubObject.SomeProperty ASC, SomeOtherProperty DESC");

See Here

Upvotes: 0

JConstantine
JConstantine

Reputation: 3931

public static IEnumerable<T> SortEmployeesFor<T>(IEnumerable<T> list, Func<T, IComparable> property1, Func<T, IComparable> property2, OrderOption option)
{
  switch (options)
  {
    case OrderOptions.1:
      return list.OrderBy(property1).ThenBy(property2);

    case OrderOptions.2:
      return list.OrderBy(property2).ThenBy(property1);
  }

  return list;
}

Then call it using something like this

list = SortEmployeesFor(list, x => x.Id, y => y.Name, OrderOptions.1);

Upvotes: 1

Davio
Davio

Reputation: 4737

Try passing in the sort properties as Funcs extracting a key from T.

So:

public static IEnumerable<T> SortEmployeesFor<T>(
  IEnumerable<T> list,
  Func<T, TProp1> order1,
  Func<T, TProp2> order2, 
  OrderOptions options)
{
    switch (options)
    {
    case OrderOptions.1:
        return list.OrderBy(order1).ThenBy(order2);

    case OrderOptions.2:
        return list.OrderBy(order2).ThenBy(order1);

    ...
    }

    return list;
}

Usage:

SortEmployeesFor<MyType>(
  list, 
  new Func<MyType, typeOfProp1>(x => x.property1), 
  new Func<MyType, typeOfProp2>(x => x.property2), 
  OrderOptions.1);

Don't know if this is exactly syntactly correct, but it should point you in the right direction.

Upvotes: 3

MaLKaV_eS
MaLKaV_eS

Reputation: 1325

You could do it with linq.

public static IEnumerable<T> SortEmployeesFor<T>(IEnumerable<T> list, OrderOptions options)
{
    switch (options)
    {
        case OrderOptions.1:
            list = from t in list
                     orderby t.property1, t.property2
                     select t;
        case OrderOptions.2:
            list = from t in list
                     orderby t.property2, t.property1
                     select t;        
        .
        .
        .
    }
    return list;
}

Upvotes: 0

Related Questions