C#.Net
- Chapter 1: Introduction to C# and .NET
- Chapter 2: C# Basics
- Chapter 3: Control Flow
- Chapter 4: Methods and Functions
- Chapter 5: Object-Oriented Programming (OOP)
- Chapter 6: Collections and Generics
- Chapter 7: Exception Handling
- Chapter 8: File I/O and Serialization
- Chapter 9: Delegates and Events
- Chapter 10: Asynchronous Programming
- Chapter 11: Working with Databases (ADO.NET)
- Chapter 12: Windows Forms and GUI Programming
- Chapter 13: Web Development with ASP.NET
- Chapter 14: Web Services and API Development
- Chapter 15: Unit Testing and Test-Driven Development (TDD)
- Chapter 16: Advanced Topics (Optional)
- Chapter 17: Best Practices and Design Patterns
- Chapter 18: Deployment and Hosting
- Chapter 19: Security in C#/.NET
- Chapter 20: Project Development and Real-World Applications
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.