c# assignment.pdf
c# assignment.pdf
submission date:
submitted to:
1
Table of Contents
page
Exception handling in c#.net...........................................................................3
2
introduction..................................................................................................3
1. Introduction to Exception Handling in C#....................................................5
1.1 What is an Exception?........................................................................5
1.2 Importance of Exception Handling......................................................5
1.3 Errors vs. Exceptions in C#................................................................6
2.Exception Handling Mechanisms in C#.....................................................7
2.1 The try, catch, and finally Blocks.........................................................8
2.2 Re-throwing Exceptions:
…………………………………………………………………12
3
Avoiding Overuse of Try-Catch Blocks.....................................................41
8. Exception Handling in Delegates and Events.........................................41
Managing Exceptions in Event-Driven Programming...............................41
Exception Handling in Callback Functions...............................................42
9. Global Exception Handling in C#............................................................43
Using AppDomain.UnhandledException in C#.........................................43
Implementing Global Exception Handling in Web Applications (ASP.NET)
................................................................................................................44
10. Debugging and Error Recovery Strategies............................................45
Using Debuggers (Visual Studio Exception Settings)...............................45
Graceful Degradation and Recovery........................................................45
11 Summery..............................................................................................46
12 References.............................................................................................47
4
Exception handling in c#.net
introduction
Exception handling in C# is a structured approach to managing runtime
errors and ensuring that applications continue functioning smoothly under
unexpected conditions. By using try, catch, finally, and throw blocks,
developers can anticipate potential failures, respond appropriately, and
prevent abrupt crashes.
5
By leveraging built-in exception types, creating custom exceptions, and
following best practices such as meaningful error logging and avoiding
generic exception catching, developers can build robust software that adapts
to varying runtime challenges. Effective exception handling not only
enhances maintainability but also contributes to an improved user
experience by providing informative error messages and graceful recovery
mechanisms.
6
1. Introduction to Exception Handling in C#
What is an Exception?
Example:
csharp
7
✅ Ensures critical resources (e.g., files, database connections) are
properly released.
try
Errors are unexpected issues that occur at a system level and often
indicate serious problems, such as:
semicolons, typos).
Exceptions
8
Exceptions are runtime issues that disrupt the normal flow of a
program but can be handled gracefully using a try-catch block.
Common exceptions include:
Key Differences
Occurrenc Compile-time or
Only at runtime
e runtime
9
Throwing Exceptions (throw Keyword)
1. Try Block: This contains the code that may cause an exception.
The try block contains the code that might throw an exception. It ensures that risky
operations (such as division by zero or accessing null references) are caught.
Example:
try
{
int num = 10;
int result = num / 0; // Exception occurs here
Console.WriteLine(result);
}
If an exception occurs inside the try block, control immediately passes to the catch
block.
10
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine($"Exception caught: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine("An unexpected error occurred.");
}
📌 Best Practice: Catch specific exceptions first before using a generic catch (Exception
ex) block.
2.1.3 The finally Block
The finally block always executes whether an exception occurs or not. It's commonly
used for cleanup operations like closing files or database connections.
The throwstatement
– Allows a user/programmer to throw an exception object
• E.g.:
throw new Exception("Exception in Throw-Test Method" );
– string passed to exception object’s constructor becomes exception object’s error
message
– Can throw only an object of class Exception or one of its derived classes
– You can customize the exception type thrown from methods
// Using finally blocks.
using System;
// demonstrating that ‘finally’ always executes
class UsingExceptions
{
entry point for application
static void Main( string[] args )
{
// Case 1: No exceptions occur in called method.
11
Console.WriteLine( "Calling DoesNotThrowException" );
DoesNotThrowException();
// Case 2: Exception occurs in called method and is caught
// in called method.
Console.WriteLine( "\nCalling ThrowExceptionWithCatch" );
Console.WriteLine( "\nCalling ThrowExceptionWithCatch" );
ThrowExceptionWithCatch();
// Case 3: Exception occurs in called method, but not caught
// in called method, because no catch handlers in called method.
Console.WriteLine( 24 "\nCalling ThrowExceptionWithoutCatch" );
// call ThrowExceptionWithoutCatch
try
{
ThrowExceptionWithoutCatch();
}
// process exception returned from
// ThrowExceptionWithoutCatch
catch
{
Console.WriteLine( "Caught exception from " + 37 "ThrowExceptionWithoutCatch in
Main" );
}
// Case 4: Exception occurs in called method and is caught
// in called method, then rethrown to caller.
Console.WriteLine( 43 "\nCalling ThrowExceptionCatchRethrow" );
// call ThrowExceptionCatchRethrow
try
12
{
ThrowExceptionCatchRethrow();
}
}
// process exception returned from
// ThrowExceptionCatchRethrow
catch
{
Console.WriteLine( "Caught exception from " + "ThrowExceptionCatchRethrow in
Main" );
}
} // end method Main
try
{
int result = 10 / 0; // Causes a divide-by-zero exception
}
catch (Exception ex)
{
Console.WriteLine("Error caught!");
14
o throw; helps developers track down the exact location of the
exception.
o throw ex; can lead to misleading stack traces, making
troubleshooting harder.
3.Exception Types in C#
Built-in Exceptions (System.Exception and Derived Classes)
15
a) System.SystemException
b) System.ApplicationException
c) System.NullReferenceException
csharp
b) Type-Related Exceptions
d) Argument Exceptions
16
System.ArgumentNullException → Raised when a null argument is
unexpectedly used.
try
{
int result = 10 / 0;
}
catch (DivideByZeroException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
This ensures that only DivideByZeroException is handled properly.
FileNotFoundExcepti
Missing file error File.ReadAllText("missing.txt
on
");
18
csharp
string text = null;
try
{
Console.WriteLine(text.Length); // Causes exception
}
catch (NullReferenceException ex)
{
Console.WriteLine("Error: The object is null.");
}
Always check if an object is null before accessing its properties.
try
{
Console.WriteLine(numbers[5]); // Causes exception
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("Error: Invalid array index.");
}
Always validate indices before accessing an array element.
19
object obj = "Hello";
int num = (int)obj; // ERROR: Cannot convert a string to an integer
Since "Hello" is a string, it cannot be cast to an int.
✅ Handling the Exception
csharp
object obj = "Hello";
try
{
int num = (int)obj; // Causes exception
}
catch (InvalidCastException ex)
{
Console.WriteLine("Error: Type conversion is invalid.");
}
Use safe conversion methods like Convert.ToInt32() or int.TryParse().
try
{
int number = int.Parse(input); // Causes exception
}
catch (FormatException ex)
{
Console.WriteLine("Error: Invalid format.");
}
Always validate user input before parsing data.
20
3.2.5. FileNotFoundException (Missing File Error)
Occurs when trying to access a file that does not exist.
Raised when using file handling methods like File.ReadAllText().
🚫 Example: Causes FileNotFoundException
csharp
string content = File.ReadAllText("nonexistent.txt"); // ERROR: File not
found
If "nonexistent.txt" does not exist, the exception occurs.
✅ Handling the Exception
csharp
try
{
string content = File.ReadAllText("nonexistent.txt"); // Causes
exception
}
catch (FileNotFoundException ex)
{
Console.WriteLine("Error: The file does not exist.");
}
Always check if the file exists before attempting to read it.
Division
DivideByZeroException int result = 10 / 0;
by zero
Accessin
NullReferenceExceptio string text = null;
g a null
n text.Length;
object
Using an
IndexOutOfRangeExce invalid array[5] on a 3-element
ption array array
index
Illegal
type (int)obj; when obj is a
InvalidCastException
conversi string
on
21
Exception Class Cause Example
invalid
data
format
Trying to
read a
non-
File.ReadAllText("missing.
FileNotFoundException existent
txt");
file
22
🟢 Optionally, add properties or methods for additional
functionality.
try
{
throw new CustomException("Something went wrong.");
}
catch (CustomException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
3.3.3 Best Practices for Custom Exceptions
4. Exception Hierarchy in C#
23
Base Class (System.Exception)
sing System;
class Program
{
static void Main()
{
try
{
string text = null;
Console.WriteLine(text.Length); // ❌ NullReferenceException
}
catch (NullReferenceException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
24
}
}
class Program
{
static void Main()
{
try
{
25
int result = 10 / 0; // ❌ DivideByZeroException
}
catch (DivideByZeroException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
🟢 Specific IO Exceptions:
26
🔹4.1. 9. Database-Related Exceptions
Example
using System;
using System.Data.SqlClient;
class Program
{
static void Main()
{
try
{
string connectionString = "InvalidConnectionString";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open(); // ❌ SqlException
}
}
catch (SqlException ex)
{
Console.WriteLine($"Database Error: {ex.Message}");
}
} 🔹 Explanation Trying to open an invalid database connection causes an
exception.
27
SocketException → Error in network socket communication.
Example:
try
Console.WriteLine($"Error: {ex.Message}");
28
Parameterized Constructor → Accepts a custom error message.
Constructor with InnerException → Wraps another exception inside.
Example:
try
Example:
try
{
throw new Exception("Main error.");
}
catch (Exception ex)
{
Console.WriteLine(ex.GetBaseException().Message);
}
4.2 Checked vs. Unchecked Exceptions
29
📌 Exceptions in C# are runtime exceptions—handled dynamically.
📌 Checked vs. Unchecked exceptions help classify errors for better handling.
🔹 Checked exceptions occur due to external issues (e.g., file or network failures).
🔹 They must be handled using try-catch to prevent program failure.
🔹 Examples include:
o FileNotFoundException → Occurs when a file is missing.
o IOException → Happens due to I/O operation failures.
o FormatException → Invalid input format errors.
Example:
try
{
int number = int.Parse("InvalidData");
}
catch (FormatException ex)
{
Console.WriteLine("Handled FormatException: " + ex.Message);
}
4.2.2 Unchecked Exceptions
Example:
try
{
int result = 5 / 0; // Causes DivideByZeroException
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Handled: " + ex.Message);
}
Key Differences
30
✅ Checked Exceptions → Must be caught or handled explicitly. ✅ Unchecked Exceptions →
Occur due to programming errors. ✅ Checked Exceptions → Typically result from external
sources. ✅ Unchecked Exceptions → Occur due to incorrect logic in code.
try
{
int num = 5 / 0; // Causes DivideByZeroException
}
catch (DivideByZeroException ex) // ✅ First match (executes)
{
32
Console.WriteLine("Error: Cannot divide by zero.");
}
catch (Exception ex) // ❌ Skipped (already handled above)
{
Console.WriteLine("General Exception caught.");
}
Order of catch Blocks Matters
✅ Start with specific exceptions, moving to general ones.
✅ Avoid placing Exception first, as it catches all errors.
✅ Prioritize critical exceptions before broader ones.
Example of Incorrect Order:
csharp
try
{
int num = int.Parse("abc"); // Causes FormatException
}
catch (Exception ex) // ❌ First catch block (catches everything)
{
Console.WriteLine("General Exception caught.");
}
catch (FormatException ex) // ❌ Never executes (already caught above)
{
Console.WriteLine("FormatException handled.");
}
Example of Correct Order:
csharp
try
{
int num = int.Parse("abc"); // Causes FormatException
}
catch (FormatException ex) // ✅ Catches first (executes)
{
Console.WriteLine("Handled: Invalid number format.");
}
catch (Exception ex) // ✅ Executes only if previous blocks fail
{
Console.WriteLine("Handled: General Exception.");
}
33
5.2 Filtering Exceptions Using catch when in C#
📌 catch when allows filtering exceptions based on specific conditions.
📌 Unlike regular catch, it executes only when the condition is true.
📌 Helps in dynamic exception handling by applying logic to errors.
📌 Reduces unnecessary exception handling when certain criteria are
met.
Key Features of catch when
🔹 Conditional Handling → Executes only when the specified condition
matches.
🔹 Selective Exception Processing → Skips exceptions that don't
meet the criteria.
🔹 Refines Error Handling → Avoids catching errors that don't need
to be processed.
🔹 Improves Debugging → Provides better control over when
exceptions are handled.
Basic Syntax of catch when
try
{
int number = int.Parse("InvalidData"); // Causes FormatException
}
catch (FormatException ex) when (ex.Message.Contains("Input string"))
{
Console.WriteLine("Filtered Exception: Invalid format detected.");
}
catch (Exception ex)
{
Console.WriteLine("General Exception caught.");
}
How catch when Works
✅ The condition inside when evaluates the exception details.
✅ If the condition is true, the exception is handled.
✅ If the condition is false, the exception bypasses the block and
moves to the next catch.
Example Flow:
try
{
throw new ArgumentException("Invalid Argument");
}
catch (ArgumentException ex) when (ex.Message.Contains("Invalid"))
34
{
Console.WriteLine("Handled: Argument Exception.");
}
catch (Exception ex)
{
Console.WriteLine("Unhandled: General Exception.");
}
Real-World Use Cases of catch when
✅ Logging Specific Exceptions → Only log critical errors, skipping minor
ones. ✅ Retry Mechanisms → Handle exceptions based on failure count. ✅
Network Errors → Catch connection errors only when retry attempts exceed
a limit. ✅ Security Filtering → Handle access-related errors based on user
roles.
Example:
int retryCount = 3;
try
{
throw new Exception("Connection failed.");
}
catch (Exception ex) when (retryCount > 2)
{
Console.WriteLine("Handled: Network error after multiple retries.");
}
35
catch (DivideByZeroException ex)
{
Console.WriteLine("Inner Catch: Division by zero error.");
throw; // Re-throws exception to outer catch block
}
try
{
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers[5]); // Causes IndexOutOfRangeException
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("Inner Catch: Array index out of bounds.");
throw; // Exception passed to outer block
}
36
}
catch (Exception ex)
{
Console.WriteLine("Outer Catch: Handling thrown exception.");
}
💡 Description:
Inner try block throws an IndexOutOfRangeException.
Inner catch handles it but re-throws it using throw;.
Outer catch then catches the error and handles it properly.
3. Deeply Nested Try-Catch Blocks
Errors bubble up through multiple nested levels.
Each level of catch handles errors and can choose to re-throw or
suppress them.
csharp
try
{
Console.WriteLine("Executing outer try block.");
try
{
try
{
throw new NullReferenceException("Inner-most error");
}
catch (NullReferenceException ex)
{
Console.WriteLine("Innermost Catch: Handling
NullReferenceException.");
throw; // Passes the error up one level
}
}
catch (Exception ex)
{
Console.WriteLine("Middle Catch: Caught an exception and re-
throwing.");
throw; // Passes the error up to the outer block
}
}
catch (Exception ex)
{
37
Console.WriteLine("Outer Catch: Final handling of exception.");
}
class Program
{
static void Main()
{
try
{
ValidateAge(15); // Call method that throws a custom exception
38
}
catch (AgeValidationException ex)
{
Console.WriteLine($"Custom Exception Caught: {ex.Message}");
}
}
39
public AgeValidationException(string message, int age) : base(message)
{
InvalidAge = age;
}
40
📌 Custom Property (InvalidAge) → Stores the invalid age that caused
the exception.
📌 Parameterized Constructor → Initializes both exception
message and custom property.
📌 Custom Method (GetExceptionDetails) → Returns detailed error
information.
📌 Exception Handling in try-catch Block → Retrieves custom error
details using a method.
Benefits of Adding Custom Properties and Methods
✅ Enhances debugging → Developers can track the exact value causing an
error. ✅ Provides structured error information → Messages are more
informative than generic ones. ✅ Encapsulates custom logic → Methods
define reusable exception-handling behaviors. ✅ Supports advanced error
logging → Easy to log detailed exception data in real-world applications.
void MethodA()
{
MethodB(); // Calls MethodB, which throws an exception
}
41
void MethodB()
{
throw new Exception("Error occurred in MethodB."); // Unhandled
exception propagates
}
42
💡 Key takeaway: A well-written message immediately tells what the issue
is and how to fix it.
43
📌 Exception handling ensures that errors in event handlers do not
affect other subscribers.
📌 Best practices include catching exceptions within event handlers
and using logging mechanisms.
Example:
csharp
public class EventPublisher
{
public event EventHandler MyEvent;
44
{
public void ExecuteCallback(CallbackDelegate callback)
{
try
{
callback("Executing callback function...");
}
catch (Exception ex)
{
Console.WriteLine($"Exception in callback: {ex.Message}");
}
}
}
45
}
46
10. Debugging and Error Recovery Strategies
Using Debuggers (Visual Studio Exception Settings)
47
try
{
int result = 10 / 0; // Causes DivideByZeroException
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Error detected, switching to safe mode.");
int result = 1; // Fallback value to maintain program stability
}
11 Summery
Exception handling in C# is a vital feature that ensures applications remain
stable and responsive even when unexpected errors occur. By using try,
catch, finally, and throw blocks, developers can structure their code to
detect, manage, and recover from runtime issues effectively.
Through proper implementation of exception handling, software becomes
more reliable and maintainable, reducing the risk of abrupt failures.
Understanding the hierarchy of exceptions and leveraging built-in exception
classes allows developers to address errors efficiently while providing
meaningful feedback to users.
Effective exception handling practices, such as using specific exception
types, logging errors, and avoiding excessive catch blocks, contribute to a
well-structured and resilient application. By mastering these techniques,
developers can build software that adapts to various runtime challenges
while ensuring a smooth user experience.
48
12 References
1. Microsoft Docs. (2023). Exception Handling (C# Programming Guide).
[https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/
exceptions/](https://learn.microsoft.com/en-us/dotnet/csharp/programming-
guide/exceptions/)
6. Freeman, A., & Jones, A. (2021). *C# 10 and .NET 6 – Modern Cross-
Platform Development. Packt.
- Chapter 4: "Debugging and Exception Handling."
49