SoFunction
Updated on 2025-03-08

A brief discussion on simple exception priming and processing operations in C#

Exception and exception handling
The exception handling function of C# language helps you handle any unexpected or exceptions that occur when the program is running. Exception handling uses the try, catch, and finally keywords to try some operations to handle failures, although these operations may fail, if you are sure you need to do this and want to clean up resources afterwards, you can try it. The Common Language Runtime (CLR), .NET Framework, or any third-party library or application code can generate exceptions. Exceptions are created using the throw keyword.
In many cases, exceptions may not be raised by methods called directly by code, but by another method located further down the call stack. In this case, the CLR expands the stack to find if there is a method that contains a catch block for that particular exception type, and if such a method is found, the first such catch block found will be executed. If no appropriate catch block is found anywhere in the call stack, the process is terminated and a message is displayed to the user.
In this example, one method is used to detect whether there is a situation where it is divided by zero; if so, the error is caught. If no exception is handled, the program will terminate and generate a "DivideByZeroException not handled" error.

class ExceptionTest
{
  static double SafeDivision(double x, double y)
  {
    if (y == 0)
      throw new ();
    return x / y;
  }
  static void Main()
  {
    // Input for test purposes. Change the values to see
    // exception handling behavior.
    double a = 98, b = 0;
    double result = 0;

    try
    {
      result = SafeDivision(a, b);
      ("{0} divided by {1} = {2}", a, b, result);
    }
    catch (DivideByZeroException e)
    {
      ("Attempted divide by zero.");
    }
  }
}

Anomaly Overview
The exception has the following characteristics:

  • All types of exceptions are ultimately derived from.
  • Use try blocks around statements that may throw exceptions.
  • Once an exception occurs in the try block, the control flow will jump to the first associated exception handler (regardless of where the handler exists in the call stack). In C#, the catch keyword is used to define exception handlers.
  • If there is no exception handler for the given exception, the program will stop executing and an error message is displayed.
  • Don't catch an exception unless you can handle an exception and keep the application in a known state. If you catch , use the throw keyword at the end of the catch block to throw the exception again.
  • If the catch block defines an exception variable, you can use it to get more information about the type of exception that occurred.
  • Programs can use the throw keyword to explicitly throw exceptions.
  • The exception object contains detailed information about the error, such as the state of the call stack and text descriptions about the error.
  • The code in the finally block is executed even if an exception occurs. Use finally blocks to free up resources, for example, to close any stream or file that is opened in a try block.

Exception of use
In C#, runtime errors in a program are propagated in the program by using a mechanism called "exception". The exception is caused by the error code encountered and is caught by the code that can correct the error. Exceptions can be raised by the .NET Framework common language runtime (CLR) or by code in the program. Once an exception is raised, the exception will be propagated up the call stack until the catch statement is found for it. Uncaught exceptions are handled by the system-provided general exception handler, which displays a dialog box.
The exception is represented by a class derived from Exception. This class identifies the type of the exception and contains properties that describe the exception in detail. Raising an exception involves creating an instance of an exception-derived class, configuring the properties of the exception (optional), and then using the throw keyword to raise the object. For example:

class CustomException : Exception
{
  public CustomException(string message)
  {

  }

}
private static void TestThrow()
{
  CustomException ex =
    new CustomException("Custom exception in TestThrow()");

  throw ex;
}



After the exception is raised, the runtime checks the current statement to determine whether it is in the try block. If so, check any catch blocks associated with the try block to determine whether they can catch the exception. A Catch block usually specifies an exception type; if the type of the catch block is the same as the type of the exception or the base class of the exception, the catch block can handle the method. For example:

static void TestCatch()
{
  try
  {
    TestThrow();
  }
  catch (CustomException ex)
  {
    (());
  }
}


If the statement that raised the exception is not in the try block, or the try block containing the statement does not have a matching catch block, the runtime will check whether there are try statements and catch blocks in the call method. The runtime continues searching for compatible catch blocks upwards in the call stack. After the catch block is found and executed, control is passed to the next statement after the catch block.
A try statement may contain multiple catch blocks. The first catch statement capable of handling the exception will be executed; any subsequent catch statements will be ignored, even if they are compatible. Therefore, in any case, catch blocks should be arranged in the order from the most specific (or the most derived degree) to the least specific. For example:

static void TestCatch2()
{
   sw = null;
  try
  {
    sw = new (@"C:\test\");
    ("Hello");
  }

  catch ( ex)
  {
    // Put the more specific exception first.
    (()); 
  }

  catch ( ex)
  {
    // Put the less specific exception last.
    (()); 
  }
  finally 
  {
    ();
  }

  ("Done"); 
}


Before executing the catch block, the runtime checks the finally block. The final block enables programmers to clear any blur state that aborted try blocks may be left behind, or to free any external resources (such as graphics handles, database connections, or file streams) without waiting for the garbage collector in the runtime to terminate these objects. For example:

static void TestFinally()
{
   file = null;
  //Change the path to something that works on your machine.
   fileInfo = new (@"C:\");

  try
  {
    file = ();
    (0xF);
  }
  finally
  {
    // Closing the file allows you to reopen it immediately - otherwise IOException is thrown.
    if (file != null)
    {
      ();
    }
  }

  try
  {
    file = ();
    ("OpenWrite() succeeded");
  }
  catch ()
  {
    ("OpenWrite() failed");
  }
}



If WriteByte() throws an exception, the code in the second try block trying to reopen the file without calling () will fail and the file will remain locked. Since you want to execute a finally block (even if an exception has been raised), the finally block in the previous example enables the file to be closed correctly, helping to avoid errors.
If no compatible catch block is found on the call stack after the exception is raised, one of three situations occurs:
If the exception occurs in the destructor, the destructor is aborted and the base destructor is called (if any).
If the call stack contains a static constructor or a static field initializer, a TypeInitializationException is raised and the original exception is assigned to the InnerException property of the new exception.
If the beginning of the thread is reached, the thread is terminated.