Почему List <T> не реализует IOrderedEnumerable <T>?
Я хотел бы работать с упорядоченными перечислениями и использовать интерфейсы как возвращаемые типы, а не конкретные типы. Мне нужно вернуть упорядоченный набор объектов. Но при использовании IList<T>
реализации я не могу вернуть IOrderedEnumerable<T>
, так как IList<T>
не наследует IOrderedEnumerable<T>
.
В примере ниже я имею модель представления с репозиторием серии, реализованную как List<T>
серийных объектов, которые, поскольку они находятся в List<T>
, упорядочены. Я метод доступа, я хочу вернуть отфильтрованный набор из серии, где возвращаются только объекты серии определенного типа, сохраняя исходный порядок среди фильтрованных элементов.
/// <summary>
/// Represents the view model for this module.
/// </summary>
public class ViewModel : AbstractViewModel
{
/// <summary>
/// Gets the series repository.
/// </summary>
/// <value>The series repository.</value>
public IList<ISeries> SeriesRepository { get; private set; }
//...
}
//8<-----------------------------
/// <summary>
/// Gets the series of the specified type.
/// </summary>
public IOrderedEnumerable<T> Series<T>() where T : ISeries
{
return ViewModel.SeriesRepository.OfType<T>(); //compiler ERROR
}
Компилятор говорит мне:
Error 14 Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<T>' to 'System.Linq.IOrderedEnumerable<T>'. An explicit conversion exists (are you missing a cast?) ...
Как я могу поддержать такой сценарий? И почему List не реализует IOrderedEnumerable?
EDIT. Чтобы уточнить мои намерения: я просто хочу объявить на уровне интерфейса, что у моего репозитория есть порядок, даже если он явно не указан ключом.
Таким образом, .ThenBy
et.al. не следует добавлять новый порядок, так как есть уже один - мой собственный и единственный.:-). Я вижу, что так вот, я пропускаю намерение .ThenBy
.
Ответы
Ответ 1
Как List<T>
реализовать IOrderedEnumerable<T>
? Это должно было бы обеспечить способ создания последующего заказа... что это значит?
Рассмотрим это:
var names = new List<string> { "Jon", "Holly", "Tom", "Robin", "William" };
var ordered = names.ThenBy(x => x.Length);
что это значит? Нет первичного порядка сортировки (как если бы я использовал names.OrderBy(x => x)
), поэтому невозможно наложить дополнительный порядок сортировки.
Я предлагаю вам попробовать создать собственную реализацию IOrderedEnumerable<T>
на основе List<T>
- при попытке реализовать метод CreateOrderedEnumerable
, я думаю, вы поймете, почему это неуместно. Вы можете найти мое сообщение в блоге Edulinq на IOrderedEnumerable<T>
.
Ответ 2
Ну, вы ошибаетесь: List<T>
НЕ, заказанный определенным ключом. Элементы внутри списка находятся в том порядке, в котором вы их вставляете. Причина, почему List<T>
не реализует IOrderedEnumerable<T>
.
Просто верните следующее:
ViewModel.SeriesRepository.OfType<T>().OrderBy(<your order predicate>);