Перейти к содержимому

Ireadonlycollection c как пользоваться

  • автор:

Почему необходимо приводить те или иные множества к IEnumerable? И Как использовать IReadOnlyCollection?

1. Много где видел, что бест практис это приводить те или иные множества к IEnumerable, не совсем понимаю зачем и где вообще это нужно применять? К примеру у меня есть класс в котором использую List и мне нужно выдать его наружу. Мне выдавать IEnumerable или List всё ж. При передачи в методах коллекций, я так понимаю лучше именно абстракцию использовать(IEnumerable), чтобы не привязываться к List’у?

2. В каких ситуациях использовать IReadOnlyCollection и его производные??

  • Вопрос задан более трёх лет назад
  • 244 просмотра

Комментировать
Решения вопроса 3

freeExec

Участник OpenStreetMap

Да просто пытаются защитить коллекцию от модификации. Когда ты на выходе получишь IEnumerable , то ты не изменить, не добавить элементы не можешь. Да и в большинстве случаев ты потом результат всё равно как последовательность обрабатываешь.

Ответ написан более трёх лет назад
Комментировать
Нравится 3 Комментировать
shai_hulud @shai_hulud

Принимай наиболее общие типы, отдавай наиболее специфичные.
На вход:
1) Если надо только перебрать элементы один раз то IEnumerable
2) Если нужен Count то IReadOnlyCollection
3) Если нужен индекс то IReadOnlyList
4) Если нужна запись, то ICollection или IList

На выход:
Наиболее специфичный тип. List<>, ReadOnlyCollection<>

Ответ написан более трёх лет назад
Нравится 2 6 комментариев
mishkaaaaaa @mishkaaaaaa

Кстати, всегда смущал этот принцип. С первой частью утверждения я согласен, а вот второй выглядит сомнительно. В EF, например, все методы IEnumerable возвращают

shai_hulud @shai_hulud

mishkaaaaaa, второй помогает писать более производительный код. Вот если у вас есть на выходе List<> или Array и вы не владеете этим списком/массивом, но отдаете его как IEnumerable, то получатель что бы получить 10000 элемент должен:
а) перебрать 9999 элементов
б) нарушить типизацию и попробовать скастовать к IList<>

Конечно возвращая IEnumerable можно менять реализацию метода как хочешь. К примеру, вместо List<> возвращать HashSet<> и за абстракцией IEnumerable это будет не видно. Или вообще сделать реализацию через генераторы.
НО очень часто такая гибкость не нужна. А перфоманс лишним не бывает, в отличии от гибкости.

cjstress

shai_hulud, перформанс нужен только тогда, когда есть проблемы с перформансом, ИМХО. Сколько задротил на проектах с перформансом — ни одного живого нет сейчас))) Я почти всегда List использую. В 95% случаев с головой хватает. А перформанс обычно улетает на какой-то сериализации.

mishkaaaaaa @mishkaaaaaa

Сергей Веремеенко, тоже удивляет, когда в разговорах про перфоманс упоминают такие вещи. Просадка производительности скорее всего будет в запросах к БД, работе с внешними API, сериализации, работе с файлами и пр. Не могу представить проект, где замена IEnumerable<> на IList<> дала бы заметный прирост

shai_hulud @shai_hulud

Сергей Веремеенко, Перфоманс нужен либам т.к. у либ всегда есть требование — «лучший перформанс за разумное время», он почти никогда не нужен продуктам т.к. там требования, в основном, про фичи. Так что не удивлен, что проекты про перфоманс мертвы.
mishkaaaaaa, Там где есть БД, про перфоманс уже можно не говорить, его похоронили. И это не связано с самими БД, он умер в голове того, кто это проектировал. Все остальные описанные кейсы параллелизуются, пулятся и вызываются асинхронно.

Как можно просесть на коллекциях я описал пример выше. Ну, и конечно можно взять коллекция на 100к элементов, потом добавить сверху LINQ, сделать OrderBy, потом Where, и вернуть ее методу который внутри ее будет итерировать для поиска каждого элемента через ElementAt. Ведь ему вернули IEnumerable<>, а он хотел IList<>, а фичу программисту надо сдавать сегодня.

yarosroman

Роман @yarosroman Куратор тега C#

mishkaaaaaa, для EF linq методы расширения возвращают IQueryable. Который от IEnumerable наследуется.

C#: коллекции только для чтения и LSP

Часто разработчики утверждают, что read-only коллекции в .NET нарушают принцип подстановки Барбары Лисков. Так ли это? Нет, это не так, потому что IList интерфейс содержит флаг IsReadOnly. Исключением является класс Array, он действительно нарушает LSP принцип начиная с версии .NET 2.0. Но давайте разберемся во всем по порядку.

История read-only коллекций в .NET

На диаграмме показано как read-only коллекции эволюционировали в .NET от версии к версии:

Как вы видите, интерфейс IList содержит два свойства: IsReadOnly и IsFixedSize. Изначальная идея была в том, чтобы разбить эти два понятия. Коллекция могла быть коллекцией только для чтения (read-only), что означало, что ее нельзя было изменить вообще никак; с другой стороны, коллекция так же могла быть фиксированного размера (fixed size), т.е. в ней можно было изменять существующие элементы, но добавлять новые или удалять имеющиеся было нельзя. Другими словами, коллекции с флагом IsReadOnly равным true всегда были IsFixedSize, но IsFixedSize коллекции не всегда были IsReadOnly.

Таким образом, если вы хотите создать свою коллекцию только для чтения, вам было бы необходимо имплементировать оба свойства (IsReadOnly и IsFixedSize) так, чтобы они возвращали true. В BCL во времена .NET 1.0 не было втроенных read-only коллекций, но архитекторы заложили фундамент для будущих реализаций. Изначальный замысел был в том, что разработчики могли бы использовать такие коллекции полиморфно примерно следующим образом:

public void AddAndUpdate(IList list) < if (list.IsReadOnly) < // No action return; >if (list.IsFixedSize) < // Update only list[0] = 1; return; >// Both add and update list[0] = 1; list.Add(1); > 

Конечно, это не самый удобный способ работы с коллекциями, но тем не менее он позволяет избежать исключений не узнавая при этом класс, стоящий за интерфейсом. Таким образом, этот дизайн не нарушает LSP. Конечно, никто не делал подобных проверок во время работы с интерфейсом IList (включая меня), поэтому вы можете слышать столько утверждений о том, что read-only коллекции нарушают LSP.

.NET 2.0

После того как в .NET 2.0 были добавлены generics, команда BCL получила возможность построить новую версию иерархии интерфейсов. Они провели некоторую работу, сделав интерфейсы коллекций более понятными. Помимо того, что они перенесли некоторые члены из IList в ICollection, они решили удалить флаг IsFixedSize.

Это было сделано потому, что массивы были единственным классом, которым этот флаг был нужен. Класс Array был единственным, кто запрещал добавлять новые или удалять имеющиеся элементы, но разрешал модификацию существующих. Команда BCL решила, что флаг IsFixedSize привносил слишком много сложности, не давая при этом почти никакой ценности. Интересно, что они изменили имплементацию флага IsReadOnly для массивов в версии .NET 2.0, так что он больше не отражал имеющееся положение вещей:

public void Test() < int[] array = < 1 >; bool isReadOnly1 = ((IList)array).IsReadOnly; // isReadOnly1 is false bool isReadOnly2 = ((ICollection)array).IsReadOnly; // isReadOnly2 is true > 

Флаг IsReadOnly возвращает true для массива, но при этом коллекцию все равно можно изменить. Вот где происходит нарушение принципа LSP. Если у нас есть метод, принимающий IList, мы не можем просто написать такой код:

public void AddAndUpdate(IList list) < if (list.IsReadOnly) < // No action return; >// Both add and update list[0] = 1; list.Add(1); > 

Если мы передадим методу объект класса ReadOnlyCollection, то (как и задумано) ничего не произойдет, т.к. коллекция является коллекцией только для чтения. С другой стороны, объект класса List (опять же, как и задумано) будет изменен: в нем будет добавлен новый элемент и изменен существующий. Но если мы передадим массив, то ничего не произойдет, т.к. массивы возвращают true для свойства ICollection.IsReadOnly. И мы никак не можем узнать, есть ли у нас возможность проапдейтить существующие элементы, кроме как с помощью проверки типа, стоящего за интерфейсом:

public void AddAndUpdate(IList list) < if (list is int[]) < // Update only list[0] = 1; return; >if (list.IsReadOnly) < // No action return; >// Both add and update list[0] = 1; list.Add(1); > 

Таким образом, массивы нарушают LSP. Заметьте, что они нарушают этот принцип только в случае если мы работаем с обобщенными (generic) интерфейсами.

Было ли это ошибкой со стороны Microsoft? Это был компромисс. Это было взвешанное решение: такая архитектура проще, но при этом нарушает LSP в одном конкретном месте.

.NET 4.5

Несмотря на то, что иерархия интерфейсов стала проще, в ней все еще имелся существенный недостаток: вам необходимо каждый раз проверять флаг IsReadOnly для того, чтобы узнать можно ли изменить коллекцию. Это не тот способ, к которому привыкли разработчики. И в общем-то, никто не использовал этот флаг для этих целей. Это свойство использовалось только в сценариях с автоматическим data binding: data binding был односторонний в случае если IsReadOnly возвращал true и двусторонный в остальных случаях.

Для остальных сценариев все просто использовали IEnumerable интерфейс либо класс ReadOnlyCollection. Для того, чтобы решить эту проблему, в .NET 4.5 были добавлены два новых интерфейса: IReadOnlyCollection и IReadOnlyList.

Эти интерфейсы были добавлены в существующую экосистему, так что архитекторы не могли допустить поломки обратной совместимости. Вот почему класс ReadOnlyCollection реализует интерфейсы IList, IList и IReadOnlyList, а не просто IReadOnlyList. Подобное изменение привело бы к ошибкам в работе существующих сборок, скомпилированных на более старых версиях .NET. Чтобы они заработали, разработчикам пришлось бы перекомпилировать их в новой версии.

Переписать всё с нуля

Не смотря на то, что имеющееся положение вещей нельзя изменить из-за требований обратной совместимости, все же интересно подумать о том, как иерархия коллекций могла бы быть сформирована сегодня, с учетом накопленных знаний.

Я думаю, что она бы выглядела следующим образом:

Вот что было сделано:
1) Необобщенные (non-generic) интерфейсы были удалены, т.к. они не добавляют ценности в общую картину.
2) Был добавлен интерфейс IFixedList, так что класс Array больше не обязан имплементировать интерфейс IList.
3) Класс ReadOnlyCollection был переименован в ReadOnlyList, т.к. это более подходящее для него имя. Так же, он теперь наследуется только от интерфейса IReadOnlyList.
4) Удалены флаги IsReadOnly и IsFixedSize. Они могут быть добавлены для сценариев с data binding, но я удалил их чтобы показать, что они больше не нужны для полиморфной работы коллекциями.

Вопрос по LSP

В BCL есть интересный пример кода:

public static int Count(this IEnumerable source) < ICollectioncollection1 = source as ICollection; if (collection1 != null) return collection1.Count; ICollection collection2 = source as ICollection; if (collection2 != null) return collection2.Count; int count = 0; using (IEnumerator enumerator = source.GetEnumerator()) < while (enumerator.MoveNext()) checked < ++count; >> return count; > 

Это имплементация метода-расширения Count для LINQ-to-objects из класса Enumerable. Входящий объект здесь тестируется на совместимость с интерфейсами ICollection и ICollection для подсчета количества элементов. Нарушает ли этот метод принцип LSP?

Нет, не нарушает. Несмотря на то, что метод проверяет объект на принадлежность к реальным классам, все эти классы имеют одинаковую имплементацию свойства Count. Другими словами, свойства ICollection.Count и ICollection.Count имеют те же постусловия (postconditions), что и выражение, подсчитывающее количество элементов в цикле while.

  • Программирование
  • .NET
  • Проектирование и рефакторинг
  • C#

Кастинг массива к IReadOnlyCollection

Свойства Count у массива и правда нету. Но для того, чтобы имплементировать интерфейс, оно и не нужно.

Есть такая штука в .NET — explicit interface implementation. Это когда класс имплементирует интерфейс, но не заводит метод с нужным именем. (Она и применяется в случае массива.)

Пример. Пусть у нас есть такой интерфейс:

interface I

Тогда мы можем сделать так:

class C : I < public void Run() < . >> 
class C : I < void I.Run() < . >> 

При этом интерфейс имплементирован в обоих случаях, но в первом случае у нас есть публичный метод Run , а во втором нету, и этот метод можно вызвать только через каст к нужному интерфейсу.

Для чего такая фича языка (explicit interface implementation) реально нужна? А вот для чего. Представьте себе, что вы хотите реализовать в классе два интерфейса, которые конфликтуют между собой, определяют функцию или свойство с одинаковым именем, которые нужно для разных интерфейсов реализовывать по-разному. Тогда вы можете написать две разные имплементации:

class C : IExecutioner, IAsyncModelObject < Task IExecutioner.Execute() < /* казним приговорённого */ >Task IAsyncModelObject.Execute() < /* начинаем работу в фоне */ >> 

Любой массив в .NET произведён от System.Array . Самой имплементации конкретных массивов в исходниках фреймворка нету, она генерируется автоматически. Документация говорит:

Starting with the .NET Framework 2.0, the Array class implements the System.Collections.Generic.IList , System.Collections.Generic.ICollection , and System.Collections.Generic.IEnumerable generic interfaces. The implementations are provided to arrays at run time, and as a result, the generic interfaces do not appear in the declaration syntax for the Array class.

В реальности, начиная с .NET 4.5, добавлены тем же механизмом ещё два интерфейса: System.Collections.Generic.IReadOnlyList and System.Collections.Generic.IReadOnlyCollection . Все эти интерфейсы реализует не класс Array , а производные от него классы, представляющие собой массивы конкретного типа.

Посмотрим интерфейсы, реализуемые типом System.Array и конкретным типом массива int[] . Такой код:

foreach (var i in typeof(System.Array).GetInterfaces()) Console.WriteLine(i); 
System.ICloneable System.Collections.IList System.Collections.ICollection System.Collections.IEnumerable System.Collections.IStructuralComparable System.Collections.IStructuralEquatable 
foreach (var i in typeof(int[]).GetInterfaces()) Console.WriteLine(i); 
System.ICloneable System.Collections.IList System.Collections.ICollection System.Collections.IEnumerable System.Collections.IStructuralComparable System.Collections.IStructuralEquatable System.Collections.Generic.IList`1[System.Int32] System.Collections.Generic.ICollection`1[System.Int32] System.Collections.Generic.IEnumerable`1[System.Int32] System.Collections.Generic.IReadOnlyList`1[System.Int32] System.Collections.Generic.IReadOnlyCollection`1[System.Int32] 

Итак, лишь конкретные массивы имплементируют IReadOnlyCollection , сам System.Array этого не делает.

Окей, но откуда же берётся сам код свойства? Заглянем в исходники .NET ( Array — базовый класс всех массивов) видим:

public abstract class Array : ICloneable, IList, IStructuralComparable, IStructuralEquatable < // . int ICollection.Count < get < return Length; >> 

Таким образом, свойства Count действительно нет, есть лишь свойство ICollection.Count , которое доступно только через каст к интерфейсу. Это показывает, откуда взялась реализация ICollection , но что же насчёт IReadOnlyCollection ? Как правильно отмечает @andreycha в соседнем ответе, для реализации generic-интерфейсов используется немного компиляторной магии и класс SZArrayHelper .

// This class is needed to allow an SZ array of type T[] to expose IList, // IList, etc., etc. all the way up to IList. When the following call is // made: // // ((IList) (new U[n])).SomeIListMethod() // // the interface stub dispatcher treats this as a special case, loads up SZArrayHelper, // finds the corresponding generic method (matched simply by method name), instantiates // it for type and executes it. 
// Этот класс (SZArrayHelper) нужен, чтобы позволить массиву T[] имплементировать // IList, IList и т. д. аж до IList. если вызывается // // ((IList) (new U[n])).МетодИзIList() // // код, отвечающий за нахождение интерфейсов в классе считает это особым случаем, // загружает SZArrayHelper, находит соответствующий обобщённый метод (просто по имени) // инстанциирует его для нужного типа T и выполняет. 

Это значит, что каст работает, но код реально находится в SZArrayHelper , и то, что этот код используется, гарантируется специальными трюками рантайма. Реальное место нахождения свойства Count — SZArrayHelper.get_Count .

IRead Only List Интерфейс

Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

Представляет доступную только для чтения коллекцию элементов, доступ к которым может быть получен по индексу.

generic public interface class IReadOnlyList : System::Collections::Generic::IEnumerable, System::Collections::Generic::IReadOnlyCollection
public interface IReadOnlyList : System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection
type IReadOnlyList = interface interface seq interface IEnumerable interface IReadOnlyCollection
type IReadOnlyList = interface interface IReadOnlyCollection interface seq interface IEnumerable
Public Interface IReadOnlyList(Of Out T) Implements IEnumerable(Of Out T), IReadOnlyCollection(Of Out T)
Параметры типа

Тип элементов в списке, доступном только для чтения.

Это ковариантный параметр типа. Это означает, что вы можете использовать любой из указанных типов или любой тип, являющийся более производным. Дополнительные сведения о ковариантности и контрвариантности см. в статье Ковариантность и контрвариантность в универсальных шаблонах.

Производный
Реализации

Комментарии

Свойства

Получает количество элементов коллекции.

Получает элемент в коллекции по указанному индексу в списке, доступном только для чтения.

Методы

Возвращает перечислитель, который осуществляет итерацию по коллекции.

Методы расширения

Создает неизменяемый массив на основе указанной коллекции.

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

Создает неизменяемый словарь на основе последовательности, подвергнутой определенному преобразованию.

Выполняет перечисление и преобразование последовательности и создает неизменяемый словарь на основе ее содержимого.

Выполняет перечисление и преобразование последовательности и создает на основе ее содержимого неизменяемый словарь с использованием указанной функции сравнения ключей.

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

Выполняет перечисление последовательности и создает неизменяемый набор хэширования на основе ее содержимого.

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

Выполняет перечисление последовательности и создает неизменяемый список на основе ее содержимого.

Выполняет перечисление и преобразование последовательности и создает неизменяемый отсортированный словарь на основе ее содержимого.

Выполняет перечисление и преобразование последовательности и создает на основе ее содержимого неизменяемый отсортированный словарь с использованием указанной функции сравнения ключей.

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

Выполняет перечисление последовательности и создает неизменяемый отсортированный набор на основе ее содержимого.

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

Возвращает объект DataTable, содержащий копии объектов DataRow при заданном входном объекте IEnumerable и универсальном параметре T , равном DataRow.

Применяет к последовательности агрегатную функцию.

Применяет к последовательности агрегатную функцию. Указанное начальное значение используется в качестве исходного значения агрегатной операции.

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

Проверяет, все ли элементы последовательности удовлетворяют условию.

Проверяет, содержит ли последовательность какие-либо элементы.

Проверяет, удовлетворяет ли какой-либо элемент последовательности заданному условию.

Добавляет значение в конец последовательности.

Возвращает входное значение, типизированное как IEnumerable .

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

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

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

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

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

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

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

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

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

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

Приводит элементы объекта IEnumerable к заданному типу.

Разбивает элементы последовательности на блоки размером не более size .

Объединяет две последовательности.

Определяет, содержится ли указанный элемент в последовательности, используя компаратор проверки на равенство по умолчанию.

Определяет, содержит ли последовательность заданный элемент, используя указанный компаратор IEqualityComparer .

Возвращает количество элементов в последовательности.

Возвращает число, представляющее количество элементов последовательности, удовлетворяющих заданному условию.

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

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

Возвращает различающиеся элементы последовательности, используя для сравнения значений компаратор проверки на равенство по умолчанию.

Возвращает различающиеся элементы последовательности, используя для сравнения значений указанный компаратор IEqualityComparer .

Возвращает отдельные элементы из последовательности в соответствии с указанной функцией селектора ключей.

Возвращает отдельные элементы из последовательности в соответствии с указанной функцией селектора ключей и с помощью указанного компаратора для сравнения ключей.

Возвращает элемент по указанному индексу в последовательности.

Возвращает элемент по указанному индексу в последовательности.

Возвращает элемент последовательности по указанному индексу или значение по умолчанию, если индекс вне допустимого диапазона.

Возвращает элемент последовательности по указанному индексу или значение по умолчанию, если индекс вне допустимого диапазона.

Находит разность множеств, представленных двумя последовательностями, используя для сравнения значений компаратор проверки на равенство по умолчанию.

Находит разность множеств, представленных двумя последовательностями, используя для сравнения значений указанный компаратор IEqualityComparer .

Создает разность наборов двух последовательностей в соответствии с указанной функцией селектора ключей.

Создает разность наборов двух последовательностей в соответствии с указанной функцией селектора ключей.

Возвращает первый элемент последовательности.

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

Возвращает первый элемент последовательности или значение по умолчанию, если последовательность не содержит элементов.

Возвращает первый элемент последовательности или указанное значение по умолчанию, если последовательность не содержит элементов.

Возвращает первый элемент последовательности, удовлетворяющий указанному условию, или значение по умолчанию, если ни одного такого элемента не найдено.

Возвращает первый элемент последовательности, удовлетворяющий условию, или указанное значение по умолчанию, если такой элемент не найден.

Группирует элементы последовательности в соответствии с заданной функцией селектора ключа.

Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и сравнивает ключи с помощью указанного компаратора.

Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и проецирует элементы каждой группы с помощью указанной функции.

Группирует элементы последовательности в соответствии с функцией селектора ключа. Ключи сравниваются с помощью компаратора, элементы каждой группы проецируются с помощью указанной функции.

Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и создает результирующее значение для каждой группы и ее ключа.

Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и создает результирующее значение для каждой группы и ее ключа. Ключи сравниваются с использованием заданного компаратора.

Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и создает результирующее значение для каждой группы и ее ключа. Элементы каждой группы проецируются с помощью указанной функции.

Группирует элементы последовательности в соответствии с заданной функцией селектора ключа и создает результирующее значение для каждой группы и ее ключа. Значения ключей сравниваются с помощью указанного компаратора, элементы каждой группы проецируются с помощью указанной функции.

Устанавливает корреляцию между элементами двух последовательностей на основе равенства ключей и группирует результаты. Для сравнения ключей используется компаратор проверки на равенство по умолчанию.

Устанавливает корреляцию между элементами двух последовательностей на основе равенства ключей и группирует результаты. Для сравнения ключей используется указанный компаратор IEqualityComparer .

Находит пересечение множеств, представленных двумя последовательностями, используя для сравнения значений компаратор проверки на равенство по умолчанию.

Находит пересечение множеств, представленных двумя последовательностями, используя для сравнения значений указанный компаратор IEqualityComparer .

Создает набор пересечения двух последовательностей в соответствии с указанной функцией селектора ключей.

Создает набор пересечения двух последовательностей в соответствии с указанной функцией селектора ключей.

Устанавливает корреляцию между элементами двух последовательностей на основе сопоставления ключей. Для сравнения ключей используется компаратор проверки на равенство по умолчанию.

Устанавливает корреляцию между элементами двух последовательностей на основе сопоставления ключей. Для сравнения ключей используется указанный компаратор IEqualityComparer .

Возвращает последний элемент последовательности.

Возвращает последний элемент последовательности, удовлетворяющий указанному условию.

Возвращает последний элемент последовательности или значение по умолчанию, если последовательность не содержит элементов.

Возвращает последний элемент последовательности или указанное значение по умолчанию, если последовательность не содержит элементов.

Возвращает последний элемент последовательности, удовлетворяющий указанному условию, или значение по умолчанию, если ни одного такого элемента не найдено.

Возвращает последний элемент последовательности, удовлетворяющий условию, или указанное значение по умолчанию, если такой элемент не найден.

Возвращает значение типа Int64, представляющее общее число элементов в последовательности.

Возвращает значение типа Int64, представляющее число элементов последовательности, удовлетворяющих заданному условию.

Возвращает максимальное значение, содержащееся в универсальной последовательности.

Возвращает максимальное значение, содержащееся в универсальной последовательности.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает максимальное значение типа Decimal.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает максимальное значение типа Double.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает максимальное значение типа Int32.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает максимальное значение типа Int64.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает максимальное значение Decimal обнуляемого типа.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает максимальное значение Double обнуляемого типа.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает максимальное значение Int32 обнуляемого типа.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает максимальное значение Int64 обнуляемого типа.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает максимальное значение Single обнуляемого типа.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает максимальное значение типа Single.

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

Возвращает максимальное значение в универсальной последовательности в соответствии с указанной функцией селектора ключа.

Возвращает максимальное значение в универсальной последовательности в соответствии с указанной функцией селектора ключей и компаратором ключей.

Возвращает минимальное значение, содержащееся в универсальной последовательности.

Возвращает минимальное значение, содержащееся в универсальной последовательности.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает минимальное значение типа Decimal.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает минимальное значение типа Double.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает минимальное значение типа Int32.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает минимальное значение типа Int64.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает минимальное значение Decimal обнуляемого типа.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает минимальное значение Double обнуляемого типа.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает минимальное значение Int32 обнуляемого типа.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает минимальное значение Int64 обнуляемого типа.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает минимальное значение Single обнуляемого типа.

Вызывает функцию преобразования для каждого элемента последовательности и возвращает минимальное значение типа Single.

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

Возвращает минимальное значение в универсальной последовательности в соответствии с указанной функцией селектора ключа.

Возвращает минимальное значение в универсальной последовательности в соответствии с указанной функцией селектора ключей и компаратором ключей.

Выполняет фильтрацию элементов объекта IEnumerable по заданному типу.

Сортирует элементы последовательности в порядке возрастания.

Сортирует элементы последовательности в порядке возрастания.

Сортирует элементы последовательности в порядке возрастания ключа.

Сортирует элементы последовательности в порядке возрастания с использованием указанного компаратора.

Сортирует элементы последовательности в порядке убывания ключа.

Сортирует элементы последовательности в порядке убывания с использованием указанного компаратора.

Сортирует элементы последовательности в порядке убывания.

Сортирует элементы последовательности в порядке убывания.

Добавляет значение в начало последовательности.

Изменяет порядок элементов последовательности на противоположный.

Проецирует каждый элемент последовательности в новую форму.

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

Определяет, совпадают ли две последовательности, используя для сравнения элементов компаратор проверки на равенство по умолчанию, предназначенный для их типа.

Определяет, совпадают ли две последовательности, используя для сравнения элементов указанный компаратор IEqualityComparer .

Возвращает единственный элемент последовательности и генерирует исключение, если число элементов последовательности отлично от 1.

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

Возвращает единственный элемент последовательности или значение по умолчанию, если последовательность пуста; если в последовательности более одного элемента, генерируется исключение.

Возвращает единственный элемент последовательности или указанное значение по умолчанию, если последовательность пуста; Этот метод создает исключение, если в последовательности имеется несколько элементов.

Возвращает единственный элемент последовательности, удовлетворяющий указанному условию, или значение по умолчанию, если такого элемента не существует; если условию удовлетворяет более одного элемента, вызывается исключение.

Возвращает единственный элемент последовательности, удовлетворяющий указанному условию, или указанное значение по умолчанию, если такого элемента не существует; Этот метод создает исключение, если условию удовлетворяет несколько элементов.

Пропускает заданное число элементов в последовательности и возвращает остальные элементы.

Возвращает новую перечислимую коллекцию, содержащую элементы из source с исключенными count элементами из конца исходной коллекции.

Пропускает элементы в последовательности, пока они удовлетворяют заданному условию, и затем возвращает оставшиеся элементы.

Пропускает элементы в последовательности, пока они удовлетворяют заданному условию, и затем возвращает оставшиеся элементы. Индекс элемента используется в логике функции предиката.

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

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

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

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

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

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

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

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

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

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

Возвращает указанное число подряд идущих элементов с начала последовательности.

Возвращает указанный диапазон смежных элементов из последовательности.

Возвращает новую перечислимую коллекцию, содержащую последние count элементов из source .

Возвращает цепочку элементов последовательности, удовлетворяющих указанному условию.

Возвращает цепочку элементов последовательности, удовлетворяющих указанному условию. Индекс элемента используется в логике функции предиката.

Создает массив из объекта IEnumerable .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *