Collections
Abdulmottaleb Elabour
1
Collections
.NET provides a standard set of types for storing and managing collections of
objects. These include resizable lists, linked lists, and sorted and unsorted dictionaries,
as well as arrays. Of these, only arrays form part of the C# language; the
remaining collections are just classes you instantiate like any other.
We can divide the types in the .NET BCL for collections into the following categories:
• Interfaces that define standard collection protocols
• Ready-to-use collection classes (lists, dictionaries, etc.)
• Base classes for writing application-specific collections
2
Enumeration
In computing, there are many different kinds of collections, ranging from simple
data structures such as arrays or linked lists, to more complex ones such as red/
black trees and hashtables. Although the internal implementation and external
characteristics
of these data structures vary widely, the ability to traverse the contents of
the collection is an almost universal need. The .NET BCL supports this need via a
pair of interfaces (IEnumerable, IEnumerator, and their generic counterparts) that
allow different data structures to expose a common traversal API. These are part of
a larger set of collection interfaces illustrated in next Figure.
3
Enumeration
4
IEnumerable and IEnumerator
The IEnumerator interface defines the basic low-level protocol by which elements
in a collection are traversed—or enumerated—in a forward-only manner. Its declaration
is as follows:
5
IEnumerable and IEnumerator
• MoveNext advances the current element or “cursor” to the next position, returning
false if there are no more elements in the collection.
• Current returns the element at the current position (usually cast from object to a
more specific type).
• MoveNext must be called before retrieving the first element—this is to allow for an
empty collection.
• The Reset method, if implemented, moves back to the start, allowing the collection
to be enumerated again.
6
IEnumerable and IEnumerator
Collections do not usually implement enumerators; instead, they provide enumerators,
via the interface IEnumerable:
By defining a single method retuning an enumerator, IEnumerable provides flexibility
in that the iteration logic can be farmed out to another class.
7
IEnumerable and IEnumerator
8
Implementing the Enumeration Interfaces
You might want to implement IEnumerable or IEnumerable<T> for one or more of the
following reasons:
• To support the foreach statement
• To interoperate with anything expecting a standard collection
• To meet the requirements of a more sophisticated collection interface
• To support collection initializers
9
C# yield keyword
• The yield keyword performs custom iteration over a collection like list, array, etc.
• Yield return is a C# keyword used in an iterator method to return one element at a time
to the calling code. Rather than creating a collection and returning it all at once.
• yield return pauses the method’s execution after each returned value, resuming from
where it left off when the next value is requested.
• This approach allows for lazy iteration, where values are generated and returned as
they are needed.
10
Benefits of yield return
• Deferred Execution: The method is executed only when the values are actually
needed. It does not execute in full right away, which is helpful in scenarios where you
may not need the entire dataset.
• Memory Efficiency: Since values are generated one at a time, you can work with large
or even infinite sequences without overwhelming memory by storing the entire
collection at once.
• Simpler Code for Iterators: Using yield return simplifies writing custom iterators. You
don’t have to manage state manually—C# does that for you.
11
Benefits of yield return
• Deferred Execution: The method is executed only when the values are actually
needed. It does not execute in full right away, which is helpful in scenarios where you
may not need the entire dataset.
• Memory Efficiency: Since values are generated one at a time, you can work with large
or even infinite sequences without overwhelming memory by storing the entire
collection at once.
• Simpler Code for Iterators: Using yield return simplifies writing custom iterators. You
don’t have to manage state manually—C# does that for you.
12
yield return Example 1
Output:
1
2
3
4 13
yield return Example 2
Output:
3
....
5
....
14
yield return Example 2
15
Dictionaries
A dictionary is a collection in which each element is a key/value pair. Dictionaries are most commonly
used for lookups and sorted lists.
.NET defines a standard protocol for dictionaries, via the interfaces Idictionary and
IDictionary <TKey, TValue>, as well as a set of general-purpose dictionary classes. The classes each
differ in the following regard:
• Whether or not items are stored in sorted sequence
• Whether or not items can be accessed by position (index) as well as by key
• Whether it’s generic or nongeneric
• Whether it’s fast or slow to retrieve items by key from a large dictionary
It is dynamic in nature means the size of the dictionary is growing according to the need.
16
Dictionaries
Key-Value Pair: The value is stored in the Key-Value pair.
Efficient Lookup: It provides fast lookups for values based on keys.
Unique Keys: Stored keys uniquely and adding duplicate keys results in a runtime
exception.
In Big-O notation, retrieval time by key is as follows:
• O(1) for Hashtable, Dictionary, and OrderedDictionary
• O(log n) for SortedDictionary and SortedList
• O(n) for ListDictionary (and nondictionary types such as List<T>)
17
Dictionaries
Dictionary classes 18
Dictionary Example
Output:
Key: 1, Value: C#
Key: 2, Value: Java script
Key: 3, Value: C++ 19
C# List Class
• In C#, the List<T> class represents the list of objects that can be accessed by index.
• It comes under the System.Collections.Generic namespace. List class can be used to
create a collection of different types like integers, strings, etc.
• List<T> class also provides the methods to search, sort, and manipulate lists.
• It is different from the arrays. A List<T> can be resized dynamically but arrays cannot.
• List<T> class can accept null as a valid value for reference types and it also allows
duplicate elements.
• If the Count becomes equal to Capacity, then the capacity of the List increases
automatically by reallocating the internal array. The existing elements will be copied to
the new array before the addition of the new element.
20
C# List Class
Method Description
Add() Used to insert a new Item in a List.
AddRange() Used to extend an existing List or join two Lists
Remove() Used to remove an element from the List by its name/value.
RemoveAt() Used to remove an element from the List by its index.
Clear() Used to remove all the elements from the List.
Sort() Used to sort a List in Ascending order.
Reverse() Used to reverse a List
Insert Insert an item at specific index
21
C# List Class
22
C# List Class
Output:
8
7
6
5
2
1
23