C#/ LINQ:如何在调用OrderBy之前为模板化类定义一个keySelector

时间:2010-06-08 10:09:01

标签: c# linq sql-order-by

我在C#

中定义了以下类
class myClass<T,U>
{
    public T PropertyOne { get; set; }
    public U PropertyTwo { get; set; }
}

我需要编写一个重新排序myClass对象列表的函数,并采用另外两个参数来定义我如何重新排序:我的重新排序是依赖于PropertyOne还是PropertyTwo,它是升序还是降序。假设这两个参数是布尔值。根据我目前在LINQ的知识,我会写:

public IList<myClass<T,U>> ReOrder(IList<myClass<T,U>> myList, bool usePropertyOne, bool ascending)
{
    if (usePropertyOne)
    {
        if (ascending)
        {
            return myList.OrderBy(o => o.PropertyOne).ToList();
        }
        else
        {
            return myList.OrderByDescending(o => o.PropertyOne).ToList();
        }
    }
    else
    {
        if (ascending)
        {
            return myList.OrderBy(o => o.PropertyTwo).ToList();
        }
        else
        {
            return myList.OrderByDescending(o => o.PropertyTwo).ToList();
        }
    }
}

这可能是一种更有效/更优雅的方式吗?我怎样才能宣布Func,TResult&gt;当我调用OrderBy或OrderByDescending时要重用的keySelector对象?我对答案很有兴趣,因为在我的现实生活中,我可以拥有两个以上的属性。

2 个答案:

答案 0 :(得分:2)

public IList<T> ReOrder<T, U>(
  IList<T> myList,
  Func<T, U> keySelector,
  bool ascending) 
{ 
  Func<IEnumerable<T>, IEnumerable<T>> orderingFunc =
    ascending ?
    x => x.OrderBy(keySelector) :
    x => x.OrderByDescending(keySelector);

  return orderingFunc(myList).ToList();
}

如果您只想将此限制为MyClass,则可以使用以下签名:

public IList<T> ReOrder<T, U, V>(
  IList<myClass<T, U>> myList,
  Func<myClass<T, U>, V> keySelector,
  bool ascending) 

如果你的问题是你有一个bool并且想要一个keySelector,但是没有keySelector变量,因为它必须返回T和U类型,那么请看这个答案:Generic Linq ordering function?

答案 1 :(得分:1)

public IList<myClass<T,U>> ReOrder(IList<myClass<T,U>> myList, Func<myClass<T,U>, object> selector, bool ascending)
{
  if (ascending)
  {
    return myList.OrderBy(selector).ToList();
  }
  else
  {
    return myList.OrderByDescending(selector).ToList();
  }
}