Exceptions are events that occur during the execution of a program, disrupting the normal flow of instructions.
int a = 1;int b = 0;int c = a/b; // This line produces a System.DivideByZeroException.int d = c; // This line is never executed.
In C#, system-defined exceptions are pre-defined by the .NET framework, while application-defined exceptions are custom exceptions created by developers.
// Here we define a custom exceptionpublic class InvalidAgeException : Exception{public InvalidAgeException(string message) : base(message){}}
In C#, try
, catch
, and finally
blocks are used to test code for exceptions and handle them if necessary.
int numerator = 10;int denominator = 0;int result = numerator / denominator;try // We catch any exception in this block.{int numerator = 10;int denominator = 0;int result = numerator / denominator;}catch (Exception ex) // This block runs if there is an exception.{Console.WriteLine("An exception occurred.");}finally // This block always runs after the prior two blocks.{Console.WriteLine("This message is always printed, even if an exception occurs.");}
In C#, some common system-defined exceptions include NullReferenceException
, IndexOutOfRangeException
, InvalidOperationException
, ArgumentException
, IOException
, and FormatException
.
NullReferenceException
: Occurs when trying to use a null object reference.IndexOutOfRangeException
: Occurs when accessing an array element with an invalid index.InvalidOperationException
: Occurs when a method call is invalid for the object’s current state.ArgumentException
: Occurs when a method is called with an invalid argument.IOException
: Occurs when there’s an error accessing a stream, file, or directory.FormatException
: Occurs when the format of an argument is invalid.In C#, exception filters, using the keyword when
, allow handling exceptions based on specific conditions within catch blocks.
try{// Make an HTTP request for a url provided by the uservar response = await client.GetAsync(url);}// This catch block has a filter which must be true for the exception to be caught.catch (HttpRequestException ex) when (ex.StatusCode == 404){Console.WriteLine("The resource requested was not found, try a different URL.");}// If the exception is not caught with the filter, the next block will try to catch the error.catch (HttpRequestException ex){// This would handle any HTTP request exception that is not a 404Console.WriteLine("An error occurred while making the request: " + ex.Message);}
In C#, exception propagation refers to how exceptions move up the call stack, and rethrowing exceptions involves passing the caught exception up to a higher level.
class Product {public string Name { get; set; }public int Quantity {get { return _quantity; }set {if (value < 0) {// The setter throws the exception, but it is up to the caller to deal with not being able to set a quantity// The error is propagated up to the callerthrow new ArgumentOutOfRangeException("Quantity cannot be negative.");}_quantity = value;}}}class Program{static void Main(string[] args){Product product = new Product();Console.WriteLine("Enter a product name: ");string name = Console.ReadLine();product.Name = name;while (true){Console.WriteLine("Enter a quantity: ");int quantity = int.Parse(Console.ReadLine());try{// The exception is thrown here when the entered quantity is negative// The error happens in the Product class, but it is caught hereproduct.Quantity = quantity;// The loop will only exit when the quantity is set successfullybreak;}catch (ArgumentOutOfRangeException ex){// We are providing a message to the user that the quantity cannot be negativeConsole.WriteLine(ex.Message, "Please enter a non-negative quantity.");}}}}
In C#, custom exception classes are created and implemented to handle application-specific errors effectively.
// Create a custom exception classpublic class InvalidAgeException : Exception{public InvalidAgeException(string message) : base(message){}}public class Program{static void ValidateAge(int age){if (age < 0 || age > 120){// Throw the custom exception classthrow new InvalidAgeException("Age must be between 0 and 120.");}}}
Best practices for exception handling include knowing when to throw exceptions, when to catch them, and avoiding the overuse of exceptions.
finally
block.In C#, the throw keyword allows developers to explicitly generate exceptions in their code, enabling them to signal specific error conditions and validate method arguments, thus contributing to more robust and maintainable applications.
if (age < 0){throw new ArgumentException("Age cannot be negative.");}