Как мне конвертировать IEnumerable в пользовательский тип в C #? - PullRequest
5 голосов
/ 14 июля 2009

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

Ответы [ 10 ]

6 голосов
/ 14 июля 2009

Если ваш тип коллекции реализует 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;
    }
}
1 голос
/ 14 июля 2009

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

1 голос
/ 14 июля 2009

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

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

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

0 голосов
/ 14 июля 2009

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

0 голосов
/ 14 июля 2009

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

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

  1. Создайте новый список самостоятельно, основываясь на результатах вашего LINQ-ing
  2. Реализация возможности сортировки в вашей пользовательской коллекции (или использование хорошей сортируемой универсальной коллекции в качестве основы), чтобы она могла сортироваться на месте.
0 голосов
/ 14 июля 2009

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

var myEnumerable = this.GetEnumerator();

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

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

public static CustomCollection<TSource> ToCustomCollection<TSource>(this IEnumerable<TSource> source);
0 голосов
/ 14 июля 2009

Перечислители и коллекции довольно разных зверей.

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

0 голосов
/ 14 июля 2009

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

Если это IList, то вы можете сделать .ToList () в IEnumerable. Если это IDictionary, то вы сможете сделать .ToDictionary () на IEnumerable Etc ..

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

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

0 голосов
/ 14 июля 2009

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

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

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

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

var list = items.ToList();
0 голосов
/ 14 июля 2009

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

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

...