Ответ
Коллекции в C# делятся на обобщённые (System.Collections.Generic) и необобщённые (System.Collections). В современной разработке используются почти исключительно обобщённые коллекции из-за типобезопасности и производительности.
Основные обобщённые коллекции:
-
List<T>— динамический массив. Быстрый доступ по индексу (O(1)), медленная вставка/удаление в середину (O(n)).var numbers = new List<int> { 1, 2, 3 }; numbers.Add(4); // Добавление в конец int second = numbers[1]; // Доступ по индексу -
Dictionary<TKey, TValue>— хеш-таблица. Быстрый доступ, добавление и удаление по ключу (в среднемO(1)). Ключи должны быть уникальными.var capitals = new Dictionary<string, string> { ["France"] = "Paris", ["Japan"] = "Tokyo" }; string city = capitals["Japan"]; // Получение по ключу -
HashSet<T>— коллекция уникальных элементов на основе хеш-таблицы. Оптимизирована для операций проверки принадлежности (Contains), объединения (UnionWith), пересечения (IntersectWith).var uniqueNumbers = new HashSet<int> { 1, 2, 2, 3 }; // Результат: {1, 2, 3} bool added = uniqueNumbers.Add(2); // Вернёт false, так как 2 уже есть -
Queue<T>— коллекция по принципу FIFO (First-In-First-Out).var queue = new Queue<string>(); queue.Enqueue("First"); queue.Enqueue("Second"); string firstItem = queue.Dequeue(); // Вернёт "First" -
Stack<T>— коллекция по принципу LIFO (Last-In-First-Out).var stack = new Stack<string>(); stack.Push("First"); stack.Push("Second"); string topItem = stack.Pop(); // Вернёт "Second" -
LinkedList<T>— двусвязный список. Очень быстрая вставка и удаление в любом месте (O(1)), если есть ссылка на узел, но медленный доступ по индексу (O(n)).
Выбор коллекции:
- Используйте
List<T>по умолчанию для простых списков. - Используйте
Dictionary<TKey, TValue>для быстрого поиска по ключу. - Используйте
HashSet<T>, когда важна уникальность и быстрая проверка наличия элемента. - Необобщённые коллекции (
ArrayList,Hashtable) считаются устаревшими и их следует избегать из-за проблем с производительностью (упаковка/распаковка) и типобезопасностью.
Ответ 18+ 🔞
Давай разберём эти ваши коллекции, а то некоторые до сих пор ArrayList юзают, как будто на дворе не 2024-й, а 2002-й год, блядь.
Смотри, в C# есть два лагеря: обобщённые (System.Collections.Generic) и необобщённые (System.Collections). Так вот, если ты сейчас пишешь новый код и лезешь в System.Collections — ты или старый пердун, который не хочет учиться, или просто еблан. Необобщённые коллекции — это прошлый век, они медленные из-за постоянной упаковки-распаковки и опасные, потому что там любой объект можно запихнуть, а потом получить InvalidCastException прямо в ебало. Забудь про них, как про плохой сон.
Теперь про нормальные, обобщённые коллекции — это наш рабочий инструмент.
Основные пацаны на районе:
-
List<T>— это типа динамический массив, самый популярный чувак. Доступ по индексу — мгновенный,O(1). Но если тебе взбредёт вставить или удалить что-то в середину — будет больно,O(n), потому что всё после этой точки придётся сдвигать.var numbers = new List<int> { 1, 2, 3 }; numbers.Add(4); // Добавили в конец — быстро int second = numbers[1]; // Достали по индексу — моментально -
Dictionary<TKey, TValue>— хеш-таблица, король поиска по ключу. В среднем все операции (добавить, найти, удалить) —O(1), что просто охуенно. Ключи должны быть уникальными, иначе он тебе мозги выест.var capitals = new Dictionary<string, string> { ["France"] = "Paris", ["Japan"] = "Tokyo" }; string city = capitals["Japan"]; // Бах — и Токио у тебя в кармане -
HashSet<T>— это какDictionary, но только для ключей. Хранит только уникальные элементы. Создан для быстрых операций: проверить, есть ли элемент (Contains), объединить два множества, найти общие элементы. Если попытаться добавить дубликат — он вежливо посылает тебя нахуй (вернётfalse).var uniqueNumbers = new HashSet<int> { 1, 2, 2, 3 }; // В итоге будет {1, 2, 3} bool added = uniqueNumbers.Add(2); // Вернёт false, потому что двойка уже есть, мудила -
Queue<T>— очередь, принцип FIFO (первым пришёл — первым ушёл). Как в магазине, только без бабулек с тележками.var queue = new Queue<string>(); queue.Enqueue("First"); queue.Enqueue("Second"); string firstItem = queue.Dequeue(); // Вытащит "First" -
Stack<T>— стек, принцип LIFO (последним пришёл — первым ушёл). Как стопка тарелок: какую положил сверху — такую и снимаешь.var stack = new Stack<string>(); stack.Push("First"); stack.Push("Second"); string topItem = stack.Pop(); // Вытащит "Second" -
LinkedList<T>— двусвязный список. Экзотический зверь. Если у тебя есть прямая ссылка на узел, то вставить или удалить рядом с ним — мгновенно,O(1). Но чтобы до этого узла добраться по индексу — придётся идти пешком через весь список,O(n). Используется редко, для специфичных оптимизаций.
Краткий гид по выбору, чтобы не выглядеть идиотом:
- Просто нужен список?
List<T>, без вариантов. - Нужно быстро что-то найти по ключу (ID, имя)?
Dictionary<TKey, TValue>, идеально. - Важна уникальность и нужно быстро проверять, есть ли элемент?
HashSet<T>, в студию. - Очередь задач или сообщений?
Queue<T>. - Отмена операций или история?
Stack<T>.
И ещё раз, для тех, кто в танке: забей хуй на ArrayList, Hashtable и всю эту необобщённую хуйню. Это legacy, от которого одни проблемы.
Видео-ответы
▶
▶
▶
▶
▶
▶