C#编程.异常处理(Exception Handling Statements)

C#语言包含结构化异常处理(Structured Exception Handling,SEH)。

throw

The throw statement is used to signal the occurrence(发生) of an anomalous(异常) situation (exception) during the program execution.

Remarks

The thrown exception is an object whose class is derived from System.Exception, as shown in the following example.

class MyException : System.Exception {}
// ...
throw new MyException();

Usually the throw statement is used with try-catch or try-finally statements. A throw statement can be used in a catch block to re-throw the exception that the catch block caught. In this case, the throw statement does not take an exception operand. For more information and examples, see try-catch (C# Reference) and How to: Explicitly Throw Exceptions.

try-catch

The try-catch statement(语句) consists of a try block fllowed by one or more catch clauses(子句),which specify handles for different exceptions.

Remarks

When an exception is thrown, the common language runtime (CLR) looks for the catch statement that handles this exception. If the currently executing method(当前方法) does not contain such a catch block, the CLR looks at the method that called the current method(调用当前方法的方法), and so on up the call stack. If no catch block is found, then the CLR displays an unhandled exception message to the user and stops execution of the program.


The try block contains the guarded code(被保护代码) that may cause the exception. The block is executed until an exception is thrown or it is completed successfully. For example, the following attempt(尝试) to cast a null object(赋值一个null对象) raises(引起) the NullReferenceException exception:

object o2 = null;
try
{
    int i2 = (int)o2;   // Error
}

Although the catch clause(子句) can be used without arguments to catch any type of exception, this usage is not recommended(不推荐这种用法). In general, you should only catch those exceptions that you know how to recover from(在大多数时候,你应该捕获你知道怎样处理的异常). Therefore, you should always specify an object argument derived from(派生于) System.Exception .For example:

catch (InvalidCastException e) 
{
}

It is possible to use more than one specific catch clause in the same try-catch statement. In this case, the order of the catch clauses(catch子句的顺序) is important because the catch clauses are examined in order(按顺序检查). Catch the more specific exceptions before the less specific ones(把一般的错误放在特殊的错误之前). The compiler produces an error if you order your catch blocks so that a later block can never be reached(如若你那样安排你catch子句的顺序,因为后面的catch永远到达不到,所以编译器会产生一个错误).Using catch arguments is one way to filter for the exceptions you want to handle(使用catch参数是一种过滤你要处理的错误的方式). 



Exception filters are preferable(最好) to catching and rethrowing (explained below) because filters leave the stack unharmed. If a later handler dumps the stack, you can see where the exception originally came from(你可以看见错误在哪里产生的), rather than just the last place it was rethrown(而不仅仅是在哪里抛出的). A common use of exception filter expressions is logging(一种最经常的用法是在日志上面). You can create a predicate function that always returns false that also outputs to a log(你可以创建一个函数,专门利用返回的错误信息生成日志), you can log exceptions as they go by without having to handle them and rethrow(你可以不马上处理和抛出,可以把异常都存入日志中).

A throw statement can be used in a catch block to re-throw the exception that is caught by the catch statement(一个throw语句可以被用在catch块中去抛出被catch块捕捉的的异常). The following example extracts source information from an IOException exception, and then throws the exception to the parent method.

catch (FileNotFoundException e)
{
    // FileNotFoundExceptions are handled here.
}
catch (IOException e)
{
    // Extract some information from this exception, and then 
    // throw it to the parent method.
    if(e.Source != null)
        Console.WriteLine("IOException source: {0}", e.Source);
    throw;
}

You can catch one exception and throw a different exception(你可以抛出和捕获的不一样的异常). When you do this, specify the exception that you caught as the inner exception(当你这样处理的时候,你捕获的特殊异常在这个异常内部), as shown in the following example.
catch (InvalidCastException e) 
{
    // Perform some action here, and then throw a new exception.
    throw new YourCustomException("Put your error message here.", e);
}

You can also re-throw an exception when a specified condition is true(你也可以判断当一个特殊的条件为true的时候抛出异常), as shown in the following example.
catch (InvalidCastException e)
{
    if (e.Data == null)
    {
        throw;
    }
    else
    {
        // Take some action.
    }
 }

From inside a try block(在一个try块内部), initialize only variables that are declared there in(只有当变量是在块内定义的时候才能初始化). Otherwise, an exception can occur before the execution of the block is completed(否则,在程序段执行完之前会产生一个错误). For example, in the following code example, the variable n is initialized inside the try block(变量n实在try块内初始化的). An attempt to use this variable outside the try block in the Write(n) statement will generate a compiler error(尝试在try块外使用Write(n)语句,使用n,那将长生一个错误).
static void Main() 
{
    int n;
    try 
    {
        // Do not initialize this variable here.
        n = 123;
    }
    catch
    {
    }
    // Error: Use of unassigned local variable 'n'.
    Console.Write(n);
}

Example1

In the following example, the try block contains a call to the ProcessString method that may cause an exception. The catch clause contains the exception handler that just displays a message on the screen. When the throw statement is called from inside MyMethod, the system looks for the catch statement and displays the message Exception caught.
 class TryFinallyTest
{
    static void ProcessString(string s)
    {
        if (s == null)
        {
            throw new ArgumentNullException();
        }
    }

    static void Main()
    {
        string s = null; // For demonstration purposes.

        try
        {            
            ProcessString(s);
        }

        catch (Exception e)
        {
            Console.WriteLine("{0} Exception caught.", e);
        }
    }
}
    /*
    Output:
    System.ArgumentNullException: Value cannot be null.
       at TryFinallyTest.Main() Exception caught.
     * */


Example2


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestSEH
{
    class Program
    {
        static string[] eTypes = {"none","simple","index","nested index"};
        static void Main(string[] args)
        {
            foreach (string eType in eTypes)
            {
                try
                {
                    Console.WriteLine("Main() try block reched.");
                    Console.WriteLine("ThrowException("{0}") called.", eType);

                    ThrowException(eType);
                    Console.WriteLine("Main() try block continues.");
                }
                catch (System.IndexOutOfRangeException e) 
                {
                    Console.WriteLine("Main() System.IndexOutOfRangeException catch" + "black reched.Message:
"{0}", e.Message);
                }
                catch
                {
                    Console.WriteLine("Main() general catch block reached.");
                }
                finally
                {
                    Console.WriteLine("Main() finally block reched.");
                }
                Console.WriteLine();
            }
            Console.ReadKey();
        }
        static void ThrowException(string exceptionType)
        {
            Console.WriteLine("ThrowException("{0}") reached.",exceptionType);
            switch (exceptionType)
            {
                case "none" :
                    Console.WriteLine("Not throwing an exception.");
                    break;
                case "simple" :
                    Console.WriteLine("Throwing System.Exception.");
                    throw (new System.Exception());
                    break;
                case "index" :
                    Console.WriteLine("Throwing System.IndexOutOfRangeException.");
                    eTypes[4] = "error";
                    break;
                case "nested index" :
                    try
                    {
                        Console.WriteLine("ThrowException("nested index")" + "try black reached.");
                        Console.WriteLine("ThrowException("index") called.");
                        ThrowException("index");
                    }
                    catch (Exception)
                    {
                        Console.WriteLine("ThrowException("nested index") general" + "catch block reached.");
                    }
                    finally
                    {
                        Console.WriteLine("ThrowException("nested index") finally"+"block reched");
                    }
                    break;
            }
        }


原文地址:https://www.cnblogs.com/haxianhe/p/9271185.html