Introduction
Creating custom exceptions in C# allows you to define application-specific error conditions. Custom exceptions provide more meaningful error messages and can encapsulate additional information about the error, making your code more robust and easier to debug.
Creating a Custom Exception
To create a custom exception, you derive a new class from the Exception
class. You can add constructors and additional properties or methods as needed.
Basic Custom Exception
Here’s a simple example of creating and using a custom exception.
Example: Basic Custom Exception
using System;
namespace CustomExceptionExample
{
// Custom exception class
public class InvalidAgeException : Exception
{
public InvalidAgeException() { }
public InvalidAgeException(string message) : base(message) { }
public InvalidAgeException(string message, Exception inner) : base(message, inner) { }
}
class Program
{
static void Main(string[] args)
{
try
{
ValidateAge(15);
}
catch (InvalidAgeException ex)
{
Console.WriteLine($"Exception caught: {ex.Message}");
}
}
static void ValidateAge(int age)
{
if (age < 18)
{
throw new InvalidAgeException("Age must be at least 18.");
}
Console.WriteLine("Age is valid.");
}
}
}
Output
Exception caught: Age must be at least 18.
Custom Exception with Additional Properties
You can enhance your custom exception by adding additional properties to provide more context about the error.
Example: Custom Exception with Additional Properties
using System;
namespace CustomExceptionWithPropertiesExample
{
// Custom exception class with additional properties
public class InvalidAgeException : Exception
{
public int Age { get; }
public InvalidAgeException() { }
public InvalidAgeException(string message) : base(message) { }
public InvalidAgeException(string message, int age) : base(message)
{
Age = age;
}
public InvalidAgeException(string message, Exception inner) : base(message, inner) { }
}
class Program
{
static void Main(string[] args)
{
try
{
ValidateAge(15);
}
catch (InvalidAgeException ex)
{
Console.WriteLine($"Exception caught: {ex.Message}");
Console.WriteLine($"Invalid Age: {ex.Age}");
}
}
static void ValidateAge(int age)
{
if (age < 18)
{
throw new InvalidAgeException("Age must be at least 18.", age);
}
Console.WriteLine("Age is valid.");
}
}
}
Output
Exception caught: Age must be at least 18.
Invalid Age: 15
Custom Exception with Serialization
If you need your custom exception to support serialization (for example, when using remoting or certain serialization frameworks), you should implement the ISerializable
interface and include the Serializable
attribute.
Example: Custom Exception with Serialization
using System;
using System.Runtime.Serialization;
namespace CustomExceptionWithSerializationExample
{
[Serializable]
public class InvalidAgeException : Exception
{
public int Age { get; }
public InvalidAgeException() { }
public InvalidAgeException(string message) : base(message) { }
public InvalidAgeException(string message, int age) : base(message)
{
Age = age;
}
public InvalidAgeException(string message, Exception inner) : base(message, inner) { }
protected InvalidAgeException(SerializationInfo info, StreamingContext context) : base(info, context)
{
Age = info.GetInt32("Age");
}
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("Age", Age);
}
}
class Program
{
static void Main(string[] args)
{
try
{
ValidateAge(15);
}
catch (InvalidAgeException ex)
{
Console.WriteLine($"Exception caught: {ex.Message}");
Console.WriteLine($"Invalid Age: {ex.Age}");
}
}
static void ValidateAge(int age)
{
if (age < 18)
{
throw new InvalidAgeException("Age must be at least 18.", age);
}
Console.WriteLine("Age is valid.");
}
}
}
Output
Exception caught: Age must be at least 18.
Invalid Age: 15
Best Practices for Custom Exceptions
- Derive from
Exception
: Derive your custom exception from theException
class or one of its subclasses. - Meaningful Names: Give your custom exception a meaningful name that clearly describes the error condition.
- Provide Constructors: Provide multiple constructors, including the default constructor, a constructor that takes a message, and a constructor that takes a message and an inner exception.
- Add Additional Properties: Add additional properties as needed to provide more context about the error.
- Support Serialization: Implement serialization if your exception needs to be serialized.
Conclusion
Custom exceptions in C# allow you to define specific error conditions for your application, providing more meaningful error messages and additional context. By creating custom exceptions, you can make your code more robust and easier to debug, ensuring that it handles errors gracefully and provides clear feedback to users and developers.