C # / LINQ: Как определить общее keySelector для шаблонного класса перед вызовом OrderBy - PullRequest
1 голос
/ 08 июня 2010

У меня есть следующий класс, определенный в 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> keySelector для повторного использования при вызове OrderBy или OrderByDescending?Я заинтересован в ответе, поскольку в моей реальной жизни у меня может быть более двух свойств.

Ответы [ 2 ]

2 голосов
/ 08 июня 2010
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, тогда посмотрите этот ответ: Универсальная функция упорядочения Linq

1 голос
/ 08 июня 2010
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();
  }
}
...