</>
Skip to content
C# lessons (26/34)

C# — Exceptions

Basic try-catch

using System;

class Program
{
    static void Main()
    {
        try
        {
            int result = 10 / 0;
        }
        catch (DivideByZeroException e)
        {
            Console.WriteLine($"Error: {e.Message}");
        }
    }
}

Multiple catch blocks

using System;

class Program
{
    static void Main()
    {
        try
        {
            string? input = Console.ReadLine();
            int number = int.Parse(input!);
            int result = 100 / number;
            Console.WriteLine($"Result: {result}");
        }
        catch (FormatException e)
        {
            Console.WriteLine($"Invalid format: {e.Message}");
        }
        catch (DivideByZeroException e)
        {
            Console.WriteLine($"Cannot divide by zero: {e.Message}");
        }
        catch (Exception e)
        {
            Console.WriteLine($"Unexpected error: {e.Message}");
        }
    }
}

finally block

using System;
using System.IO;

class Program
{
    static void Main()
    {
        StreamReader? reader = null;
        try
        {
            reader = new StreamReader("file.txt");
            string content = reader.ReadToEnd();
            Console.WriteLine(content);
        }
        catch (FileNotFoundException)
        {
            Console.WriteLine("File not found");
        }
        finally
        {
            reader?.Close();
            Console.WriteLine("Cleanup complete");
        }
    }
}

Using statement

using System;
using System.IO;

class Program
{
    static void Main()
    {
        // Automatically calls Dispose
        using (var reader = new StreamReader("file.txt"))
        {
            Console.WriteLine(reader.ReadToEnd());
        }

        // C# 8 using declaration
        using var writer = new StreamWriter("output.txt");
        writer.WriteLine("Hello, file!");
    }
}

Custom exceptions

using System;

public class InsufficientFundsException : Exception
{
    public decimal Balance { get; }
    public decimal Amount { get; }

    public InsufficientFundsException(decimal balance, decimal amount)
        : base($"Cannot withdraw {amount:C}. Balance: {balance:C}")
    {
        Balance = balance;
        Amount = amount;
    }
}

public class BankAccount
{
    public decimal Balance { get; private set; }

    public BankAccount(decimal initial) => Balance = initial;

    public void Withdraw(decimal amount)
    {
        if (amount > Balance)
            throw new InsufficientFundsException(Balance, amount);
        Balance -= amount;
    }
}

class Program
{
    static void Main()
    {
        var account = new BankAccount(100);
        try
        {
            account.Withdraw(150);
        }
        catch (InsufficientFundsException e)
        {
            Console.WriteLine(e.Message);
            Console.WriteLine($"Tried to withdraw: {e.Amount}");
        }
    }
}

Exception filters

using System;
using System.Net.Http;

class Program
{
    static async Task Main()
    {
        try
        {
            using var client = new HttpClient();
            var response = await client.GetAsync("https://invalid.example.com");
        }
        catch (HttpRequestException e) when (e.StatusCode == System.Net.HttpStatusCode.NotFound)
        {
            Console.WriteLine("Page not found");
        }
        catch (HttpRequestException e)
        {
            Console.WriteLine($"HTTP error: {e.Message}");
        }
    }
}

throw vs throw ex

using System;

class Program
{
    static void Process()
    {
        try
        {
            DoWork();
        }
        catch (Exception e)
        {
            // Good: preserves stack trace
            throw;

            // Bad: loses stack trace
            // throw e;
        }
    }

    static void DoWork()
    {
        throw new InvalidOperationException("Something went wrong");
    }
}

Common exceptions

ExceptionWhen
ArgumentNullExceptionNull argument
ArgumentExceptionInvalid argument
InvalidOperationExceptionInvalid state
NotSupportedExceptionOperation not supported
KeyNotFoundExceptionDictionary key not found
IndexOutOfRangeExceptionArray index out of bounds
FormatExceptionInvalid format
IOExceptionI/O error
NullReferenceExceptionNull dereference

Best practices

  • Catch specific exceptions, not generic Exception
  • Use finally or using for cleanup
  • Don't catch exceptions you can't handle
  • Use custom exceptions for domain-specific errors
  • Always use throw (not throw ex) to preserve stack traces

Mini Practice

Write C# code that:

  1. Creates a custom exception class
  2. Uses try-catch-finally with file operations
  3. Demonstrates exception filters with when
  4. Shows the difference between throw and throw ex

Up Next

Congratulations! You've completed the C# fundamentals. Continue exploring advanced topics like LINQ, async/await, and design patterns.

Related Topics

Frequently Asked Questions about Exceptions

What is Exceptions in C#?

Exceptions is a fundamental concept in C#. This lesson explains it step by step with clear examples, making it easy for beginners to understand.

How do I learn Exceptions?

Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Exceptions.

Why is Exceptions important in C#?

Exceptions is essential for C# development. Understanding this concept will help you write better code and solve real-world problems more effectively.