C# Exceptions Explained Simply

Exceptions in C# are unexpected events that occur while your program is running. They disrupt the normal flow of your application — but the good news is, they can be handled.

C# provides a way to catch and manage these exceptions gracefully using the try-catch block, so your app doesn’t crash when something goes wrong.


What Is an Exception?

An exception is an object that represents an error or unexpected behavior in your application. For example:

  • Dividing a number by zero
  • Trying to open a file that doesn’t exist
  • Accessing a null object

Instead of letting your app crash, you can "catch" exceptions and decide what to do next.

try
{
    int result = 10 / 0; // This will throw an exception
}
catch (DivideByZeroException ex)
{
    Console.WriteLine("You can't divide by zero!");
}

Types of Exceptions

You can group exceptions in C# into three main categories:

1. Base Exception

  • The root of all exceptions in .NET is the System.Exception class.
  • All other exceptions inherit from this base class.

Example:

catch (Exception ex)
{
    // Catches any kind of exception
    Console.WriteLine("Something went wrong: " + ex.Message);
}

2. Specific Exceptions

  • These are built-in exceptions that target specific problems.
  • They inherit from the base Exception class.

Common examples:

  • DivideByZeroException
  • NullReferenceException
  • FileNotFoundException

Using specific exceptions helps you write more precise error handling.

3. Custom Exceptions

  • You can also create your own exceptions by extending the Exception class.
  • Useful when building larger applications or frameworks where you want custom error reporting.
public class InvalidUserInputException : Exception
{
    public InvalidUserInputException(string message) : base(message) {}
}

Why Use Try-Catch?

The try-catch block lets you:

  • Prevent your app from crashing
  • Log errors
  • Show friendly messages to users
  • Recover or retry failed operations

Always be careful not to overuse catch (Exception), as it can mask real bugs. Prefer catching specific exceptions when possible.


Pro Tip:

You can also use a finally block to run code after try and catch, whether an exception was thrown or not:

try
{
    // risky code
}
catch (Exception ex)
{
    // handle error
}
finally
{
    // clean up resources, close files, etc.
}

Summary

  • Exceptions happen at runtime and can be caught using try-catch.
  • Always catch specific exceptions when possible.
  • Use custom exceptions when you want to define your own error logic.
  • A finally block is helpful for clean-up tasks.