Я использую методы расширения OrderBy и ThenBy для сортировки моей пользовательской коллекции по нескольким полям. Эта сортировка не влияет на коллекцию, а вместо этого возвращает и IEnumberable. Я не могу передать результат IEnumerable в свою настраиваемую коллекцию. Есть ли способ изменить порядок моей коллекции или преобразовать результат IEnumerable в мою настраиваемую коллекцию?

5
Tony D 14 Июл 2009 в 00:46

10 ответов

Лучший ответ

Если ваш тип коллекции реализует IList<T> (чтобы иметь возможность Add() к нему), вы можете написать метод расширения:

public static Extensions
{
    public static TColl ToTypedCollection<TColl, T>(this IEnumerable ien)
        where TColl : IList<T>, new()
    {
        TColl collection = new TColl();

        foreach (var item in ien)
        {
            collection.Add((T) item);
        }

        return collection;
    }
}
6
Kenan E. K. 13 Июл 2009 в 21:16

Нет, нет. Когда вы используете операторы запроса, он не использует экземпляры исходной коллекции для создания перечисления. Скорее, он использует частные реализации (возможно, анонимные, а возможно, и нет) для обеспечения этой функциональности.

Если вы хотите, чтобы он был в вашей исходной коллекции, у вас должен быть конструктор для типа, который принимает IEnumerable<T> (или все, что хранится в вашей коллекции, если это определенно), а затем передать запрос конструктору.

Затем вы можете использовать это для создания метода расширения для IEnumerable<T> под названием To<YourCollectionType>, который будет принимать IEnumerable<T>, а затем передавать его конструктору вашего типа и возвращать его.

1
casperOne 13 Июл 2009 в 20:52

Нет. Вы можете следовать шаблону, установленному методами расширения ToList и ToDictionary - написать аналогичный метод расширения для загрузки собственного типа коллекции из IEnumerable.

1
Daniel Earwicker 13 Июл 2009 в 20:52

Вы можете написать свой собственный экземпляр IComparer, чтобы иметь возможность сортировать свою коллекцию.

Грубая сила: вы можете пройти через IEnumerable и выгрузить каждый элемент обратно в новый экземпляр вашей пользовательской коллекции.

0
MisterHux 13 Июл 2009 в 20:52

Вы можете инициализировать список с помощью IEnumerable:

Если items имеет тип IEnumerable, вы можете создать такой список:

var list = new List<string>(items);

Или вы можете просто вызвать items.ToList () :

var list = items.ToList();
0
Philippe Leybaert 13 Июл 2009 в 20:52

Какие интерфейсы реализованы в вашей пользовательской коллекции?

Если это IList, вы могли бы использовать .ToList () в IEnumerable. Если это IDictionary, вы могли бы использовать .ToDictionary () в IEnumerable Etc ..

Чтобы довести его до чего-то более подходящего для вас.

Вы можете написать метод расширения для IEnumerable для .ToMyCollection (), если нет ничего похожего.

0
NikolaiDante 13 Июл 2009 в 20:53

Перечисления и коллекции - довольно разные звери.

Перечисления позволяют выполнять только перечисление, в то время как коллекции имеют основанные на индексе средства доступа, свойство Count и тому подобное. Чтобы создать коллекцию, вам действительно нужно будет перечислить IEnumerable. Типичные коллекции, такие как List , будут иметь конструктор, принимающий IEnumerable. Тем не менее, перечисление будет выполнено.

0
flq 13 Июл 2009 в 20:53

Если вы посмотрите в класс System.Linq.Enumerable, есть несколько методов расширения, которые позволят вам преобразовать тип IEnumerable в массив или ToList.

var myEnumerable = this.GetEnumerator();

var array = myEnumerable.ToArray();
var list myEnumerable.ToList();

Вы можете последовать этому подходу и создать собственный метод расширения, который будет преобразован в вашу собственную коллекцию.

public static CustomCollection<TSource> ToCustomCollection<TSource>(this IEnumerable<TSource> source);
0
Rohan West 13 Июл 2009 в 20:54

LINQ хорош, потому что он рассматривает исходные коллекции, как этот, как неизменяемые - он не изменяет их. Использование методов расширения просто перечисляет их в указанном вами альтернативном порядке - вы не создаете НОВЫЙ настраиваемый список таким образом.

Я бы предложил два варианта:

  1. Создайте новый список самостоятельно на основе результатов LINQ-ing
  2. Реализуйте возможность сортировки в своей настраиваемой коллекции (или используйте удобную сортируемую универсальную коллекцию в качестве основы), чтобы ее можно было сортировать на месте.
0
n8wrl 13 Июл 2009 в 20:55

Вам действительно нужен особый тип коллекции? Похоже, что все, что вы хотите с этим делать, предоставляется существующими типами общих коллекций, и, возможно, вам просто нужно добавить метод расширения или для них.

0
Joel Coehoorn 13 Июл 2009 в 21:21