Drani Academy – Interview Question, Search Job, Tuitorials, Cheat Sheet, Project, eBook

C#.Net

Tutorials – C#.Net

 
Chapter 6: Collections and Generics


Chapter 6 of our C# tutorial introduces you to the world of collections and generics. Collections are an essential part of C# programming, allowing you to work with groups of objects efficiently. Generics, on the other hand, enable you to create reusable and type-safe code. In this chapter, you’ll learn about various collection types, how to use them, and how to leverage generics in your C# applications.

6.1 Introduction to Collections

In C#, a collection is a data structure that can hold multiple values. Collections are used to manage and manipulate groups of related objects or data. They are more versatile than arrays because they can dynamically grow or shrink, making them suitable for a wide range of scenarios.

C# provides a rich set of collection types, each designed for specific use cases. Common collection types include arrays, lists, dictionaries, queues, and sets. Let’s explore some of these collection types and their use cases.

6.2 Arrays

Arrays are a fundamental and straightforward collection type in C#. An array is a fixed-size data structure that can hold elements of the same type. Elements in an array are accessed by their index, starting from 0.

Here’s how you declare and initialize an array in C#:

int[] numbers = new int[5]; // Declare an integer array with 5 elements
int[] numbers = { 1, 2, 3, 4, 5 }; // Initialize an integer array with values
 

Arrays are useful when you have a fixed number of elements and need efficient random access. However, they cannot change in size once created.

6.3 Lists

A List is a dynamic collection that can grow or shrink as needed. It’s part of the System.Collections.Generic namespace. Lists are more flexible than arrays and are widely used in C# applications.

Here’s how you declare and use a List:

List<int> numbers = new List<int>(); // Declare an empty list of integers
numbers.Add(1); // Add elements to the list
numbers.Add(2);
numbers.Add(3);
int firstNumber = numbers[0]; // Access elements by index

Lists are particularly useful when you need a collection that can change in size and provides methods for adding, removing, and manipulating elements.

6.4 Dictionaries

A Dictionary is a key-value pair collection. Each element in a dictionary has a unique key associated with a value. Dictionaries are efficient for looking up values by their keys.

Here’s how you declare and use a dictionary:

Dictionary<string, int> ages = new Dictionary<string, int>(); // Declare an empty dictionary
ages["Alice"] = 30; // Add key-value pairs to the dictionary
ages["Bob"] = 25;
ages["Carol"] = 35;
int aliceAge = ages["Alice"]; // Access values by key

Dictionaries are suitable when you need to perform quick lookups based on keys, such as retrieving data associated with a unique identifier.

6.5 Queues

A Queue is a collection designed for a first-in, first-out (FIFO) order. Elements are added at the back and removed from the front. Queues are often used for managing tasks or requests in a sequential manner.

Here’s how you declare and use a queue:

Queue<string> tasks = new Queue<string>(); // Declare an empty queue
tasks.Enqueue("Task 1"); // Add elements to the back of the queue
tasks.Enqueue("Task 2");
tasks.Enqueue("Task 3");
string nextTask = tasks.Dequeue(); // Remove and retrieve the front element

Queues are suitable for scenarios where you need to process items in the order they were added, such as processing tasks in a queue.

6.6 Sets

A Set is a collection that stores unique elements. Sets are useful when you need to maintain a collection of distinct values without duplicates.

Here’s how you declare and use a set:

HashSet<int> uniqueNumbers = new HashSet<int>(); // Declare an empty set of integers
uniqueNumbers.Add(1); // Add elements to the set
uniqueNumbers.Add(2);
uniqueNumbers.Add(1); // This won't add a duplicate
int uniqueCount = uniqueNumbers.Count; // Get the number of unique elements

Sets are suitable when you need to ensure that a collection contains distinct values, and you don’t want to manage duplicates manually.

6.7 Generics

Generics are a powerful feature in C# that enable you to create reusable and type-safe code. They allow you to write classes, methods, and interfaces that work with various data types, providing flexibility and compile-time type checking.

Generics are commonly used in collection classes like List, Dictionary, and Queue to make them more versatile and type-safe. Let’s explore how generics work and how you can create your own generic classes and methods.

6.7.1 Generic Classes

A generic class is a class that can work with different data types. It’s defined using type parameters, enclosed in angle brackets (<T> by convention). Type parameters represent the data type that the class will operate on.

Here’s an example of a generic class:

public class Box<T>
{
private T value;
public Box(T initialValue)
{
value = initialValue;
}
public T GetValue()
{
return value;
}
}

In this example, the Box class is generic and can hold values of any data type. You specify the data type when creating an instance of the class:

Box<int> intBox = new Box<int>(42);
int value = intBox.GetValue(); // Retrieves an integer
Box<string> stringBox = new Box<string>("Hello, world!");
string text = stringBox.GetValue(); // Retrieves a string

 

Generic classes are valuable for creating reusable components that work with different data types.

6.7.2 Generic Methods

In addition to generic classes, C# supports generic methods. A generic method is a method that can work with different data types. You define the type parameter(s) for a generic method in angle brackets.

Here’s an example of a generic method:

public static T GetMax<T>(T a, T b)
{
return Comparer<T>.Default.Compare(a, b) > 0 ? a : b;
}

In this example, the GetMax method is generic and can compare values of any data type. You specify the data type when calling the method:

int maxInt = GetMax(5, 8); // Returns 8
string maxString = GetMax("apple", "banana"); // Returns "banana"

Generic methods are useful for creating functions that work with different data types while ensuring type safety.

6.8 Collection Initializers

C# allows you to initialize collections in a concise and readable way using collection initializers. Collection initializers are available for types that implement the IEnumerable interface, such as lists, dictionaries, and sets.

Here’s an example of a collection initializer:

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; // Initialize a list

Collection initializers make it easy to populate collections with initial values, enhancing code readability.

6.9 LINQ (Language-Integrated Query)

LINQ is a powerful feature in C# that enables you to query and manipulate data in a declarative way. LINQ stands for Language-Integrated Query, and it provides a set of methods and query expressions for working with collections, databases, XML, and more.

With LINQ, you can perform operations like filtering, sorting, grouping, and projecting data with ease. It’s a valuable tool for working with collections of objects.

Here’s an example of LINQ in action:

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
var evenNumbers = from num in numbers
where num % 2 == 0
select num;

In this example, we use LINQ to select even numbers from a list of integers.

6.10 Conclusion of Chapter 6

In Chapter 6, you’ve explored collections and generics in C#. Collections are fundamental for managing and manipulating groups of related objects efficiently. You’ve learned about various collection types, including arrays, lists, dictionaries, queues, and sets, each with its specific use cases.

Generics, a powerful feature in C#, allow you to create reusable and type-safe code. You’ve seen how to create generic classes and methods to work with different data types, enhancing code flexibility and type safety.

Additionally, you’ve learned about collection initializers and how LINQ simplifies data manipulation through declarative query expressions. Understanding collections and generics is essential for building versatile and efficient C# applications, as they provide the foundation for many programming tasks.

Scroll to Top