An exception in C# is an object that represents an error that occurs during the execution of a program. When an exception occurs, the normal flow of the program is interrupted. Then a block called try-catch
is searched for to capture (and handle) the error.
That is, when an exception occurs, it can,
- Be caught by a
try-catch
block - If not, it goes to the function that invoked the one that generated the error
If there is no try-catch
block to capture the exception, it goes “upward.” If no one handles it, the exception will reach the main function (the normal outcome is that the program terminates abruptly).
In C#, exceptions are objects of a class that inherits from the base class Exception
. These classes provide properties and methods to obtain information about the error and take actions based on the exception.
Throwing an exception
In C#, we can throw an exception ourselves using the throw
keyword. By throwing an exception, we are indicating that an error has occurred and we want to notify the program.
throw new Exception("An error occurred");
In the previous example, we are throwing an exception of type Exception
with a specific error message. This message can be used later to identify the error and take the necessary actions.
Predefined exceptions
In C#, there are different types of exceptions that we can catch using the try-catch
block. Some examples of common exceptions are:
NullReferenceException
Occurs when you try to access a member of an object that is null
. For example
string name = null;
int length = name.Length; // Will throw NullReferenceException
IndexOutOfRangeException
Is thrown when you try to access an index that is out of the range of a collection or an array. For example
int[] numbers = {1, 2, 3};
int value = numbers[5]; // Will throw IndexOutOfRangeException
DivideByZeroException
Occurs when you try to divide a number by zero. For example
int divisor = 0;
int result = 10 / divisor; // Will throw DivideByZeroException
FileNotFoundException
Is thrown when you try to access a file that does not exist. For example
using (StreamReader reader = new StreamReader("non_existent_file.txt"))
{
string content = reader.ReadToEnd(); // Will throw FileNotFoundException
}
ArgumentException
Occurs when an argument passed to a method is invalid. For example
void SetAge(int age)
{
if (age < 0) throw new ArgumentException("Age cannot be negative.");
}
SetAge(-5); // Will throw ArgumentException
InvalidOperationException
Occurs when the state of the object is not valid for the operation being performed. For example
List<int> list = new List<int>();
int value = list[0]; // Will throw InvalidOperationException if the list is empty
FormatException
Occurs when a type conversion operation fails due to an incorrect format. For example
string number = "abc";
int value = int.Parse(number); // Will throw FormatException
IOException
Is thrown in input/output error situations, such as problems reading from or writing to a file. For example
using (StreamWriter writer = new StreamWriter("file.txt"))
{
writer.WriteLine("Hello World"); // Will throw IOException if there is a problem with the file
}
:::::::
TimeoutException
: Occurs when an operation exceeds the allowed timeout. For example, in network or database operations:
// Simplified example
var client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(1); // Short timeout for the example
var response = await client.GetAsync("https://www.example.com"); // Will throw TimeoutException if the timeout is exceeded
These are just a few examples, but there are many predefined exceptions in C#.
Creating your own exceptions in .NET
In addition to using predefined exceptions in .NET, it is possible to create our own custom exceptions. This allows us to be more specific when handling errors in your applications.
To create our own exceptions, we simply need to create a class that inherits from the base class Exception
(then you can add any property or method you need to provide additional information about the error).
Here is an example of a custom exception class:
public class MyException : Exception
{
public MyException(string message) : base(message) { }
public MyException(string message, Exception innerException) : base(message, innerException) { }
}
In the code above,
- The class
MyException
inherits from the classException
- It adds two constructors to provide an error message and the possibility to include an inner exception.
Once you have your custom exception class, you can use it in your code just like you would use any other .NET exception. For example:
try
{
// Code that may throw an exception
throw new MyException("Error in my application");
}
catch (MyException ex)
{
// Handling the custom exception
}