C# 異常處理

在這里,您將學(xué)習(xí)使用try,catch和finally塊在C#中進行異常處理的知識。

必須處理應(yīng)用程序中的異常,以防止程序崩潰和意外結(jié)果,記錄異常并繼續(xù)執(zhí)行其他功能。C#提供內(nèi)置支持使用 try,catch和finally塊 來處理異常。

語法:

try
{
    // 將代碼放在這里可能會引發(fā)異常
}
catch
{
    // 在這里處理異常
}
finally
{
    // 最終清理代碼
}

try 塊:任何可能引發(fā)異常的可疑代碼都應(yīng)放在一個try{ }塊中。在執(zhí)行過程中,如果發(fā)生異常,則控制流跳至第一個匹配catch塊。

catch :catch塊是異常處理程序塊,您可以在其中執(zhí)行一些操作,例如記錄和審核異常。catch塊采用異常類型的參數(shù),您可以使用該參數(shù)獲取異常的詳細信息。

finally :finally無論是否引發(fā)異常,都將始終執(zhí)行該塊。通常,finally應(yīng)該使用一個塊來釋放資源,例如,關(guān)閉在try塊中打開的任何流或文件對象。

如果您輸入非數(shù)字字符,則以下內(nèi)容可能會引發(fā)異常。

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Enter a number: ");

        var num = int.Parse(Console.ReadLine());

        Console.WriteLine($"Squre of {num} is {num * num}");
    }
}

要在上面的示例中處理可能的異常,請將代碼包裝在一個try塊中,然后在catch塊中處理異常,如下所示。

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Console.WriteLine("Enter a number: ");

            var num = int.parse(Console.ReadLine());

            Console.WriteLine($"Squre of {num} is {num * num}");
        }
        catch
        {
            Console.Write("Error occurred.");
        }
        finally
        {
            Console.Write("Re-try with a different number.");
        }
    }
}

在上面的示例中,我們將此代碼包裝在一個try塊中。如果try塊內(nèi)發(fā)生異常,則程序?qū)⑻D(zhuǎn)到該catch塊。在catch塊內(nèi),我們將顯示一條消息以指示用戶有關(guān)其錯誤的信息,在finally塊內(nèi),我們將顯示一條有關(guān)運行程序后的操作的消息。

try塊必須跟catch或finally或兩種嵌段。在try不使用塊catch或finally塊將給出一個編譯時錯誤。

理想情況下,catch塊應(yīng)包含內(nèi)置或自定義異常類的參數(shù)以獲取錯誤詳細信息。以下包括Exception捕獲所有類型的異常的type參數(shù)。

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Console.WriteLine("Enter a number: ");

            var num = int.parse(Console.ReadLine());

            Console.WriteLine($"Squre of {num} is {num * num}");
        }
        catch(Exception ex)
        {
            Console.Write("Error info:" + ex.Message);
        }
        finally
        {
            Console.Write("Re-try with a different number.");
        }
    }
}

異常過濾器

您可以使用catch具有不同異常類型參數(shù)的多個塊。這稱為異常過濾器。當您想以不同的方式處理不同類型的異常時,異常過濾器很有用。

class Program
{
    static void Main(string[] args)
    {
        Console.Write("Please enter a number to divide 100: ");
        
        try
        {
            int num = int.Parse(Console.ReadLine());

            int result = 100 / num;

            Console.WriteLine("100 / {0} = {1}", num, result);
        }
        catch(DivideByZeroException ex)
        {
            Console.Write("不能被零除。請再試一次.");
        }
        catch(InvalidOperationException ex)
        {
            Console.Write("無效操作。請再試一次.");
        }
        catch(FormatException  ex)
        {
            Console.Write("不是有效格式。 請再試一次.");
        }
        catch(Exception  ex)
        {
            Console.Write("發(fā)生錯誤!請再試一次.");
        }
    }

}

在上面的示例中,我們指定了catch具有不同異常類型的多個塊。我們可以根據(jù)錯誤向用戶顯示適當?shù)南ⅲ虼擞脩舨粫俅沃貜?fù)相同的錯誤。

注意:
不允許具有相同異常類型的多個catch塊。具有基異常類型的catch塊必須是最后一個塊。

無效的catch塊

在同一 try..catch語句中不允許使用無參數(shù)catch塊和帶有Exception參數(shù)的catch塊,因為它們都執(zhí)行相同的操作。

try
{
    //可能引發(fā)異常的代碼
}
catch //不能同時具有catch和catch(Exception 異常)
{ 
    Console.WriteLine("Exception occurred");
}
catch(Exception ex) //不能同時具有catch和catch(異常異常)
{
    Console.WriteLine("Exception occurred");
}

另外,無參數(shù) catch 塊 catch {}或通用 catch 塊 catch (Exception ex){}必須是最后一個塊。如果在 catch {}或 catch (Exception ex)塊之后還有其他 catch 塊,編譯器將給出錯誤。

    示例:無效的catch 捕獲

try
{
    //可能引發(fā)異常的代碼
}
catch
{ 
    // 該捕獲塊必須是最后一個塊
}
catch (NullReferenceException nullEx)
{
    Console.WriteLine(nullEx.Message);
}
catch (InvalidCastException inEx)
{
    Console.WriteLine(inEx.Message);
}

finally 塊

finally塊是可選塊,應(yīng)在try或catch塊之后。無論是否發(fā)生異常,都將始終執(zhí)行 finally 塊。finally塊通常用于清理代碼,例如處理非托管對象。

    示例:finally塊

static void Main(string[] args)
{
    FileInfo file = null;

    try
    {
        Console.Write("Enter a file name to write: ");
        string fileName = Console.ReadLine();
        file = new FileInfo(fileName);
        file.AppendText("Hello World!")
    }
    catch(Exception ex)
    {
        Console.WriteLine("Error occurred: {0}", ex.Message );
    }
    finally
    {
        // 在這里清理文件對象;
        file = null;
    }
}
finally不允許使用 多個塊。另外,finally塊不能包含return,continue或break關(guān)鍵字。它不允許控制權(quán)離開finally塊。

嵌套try-catch

C#允許嵌套try-catch塊。當使用嵌套的try-catch塊時,將在發(fā)生異常catch的try塊之后的第一個匹配塊中捕獲異常。

static void Main(string[] args)
{
    var divider = 0;

    try
    {
        try
        {
            var result = 100/divider;
        }
        catch
        {
            Console.WriteLine("Inner catch");
        }
    }
    catch
    {
        Console.WriteLine("Outer catch");
    }
}
輸出:
Inner catch

catch在上面的示例中,將執(zhí)行一個內(nèi)部塊,因為它是catch處理所有異常類型的第一個塊。

如果沒有與拋出的異常類型匹配的內(nèi)部catch塊,則控制將流向外部catch塊,直到找到合適的異常篩選器??聪旅娴膶嵗?br/>

static void Main(string[] args)
{
    var divider = 0;

    try
    {
        try
        {
            var result = 100/divider;
        }
        catch(NullReferenceException ex)
        {
            Console.WriteLine("Inner catch");
        }
    }
    catch
    {
        Console.WriteLine("Outer catch");
    }
}
輸出:
Outer catch

在上面的示例中,將引發(fā)類型異常 DivideByZeroException 。由于內(nèi)部catch塊僅處理NullReferenceTypeException,因此將由外部catch塊處理。

丰满人妻一级特黄a大片,午夜无码免费福利一级,欧美亚洲精品在线,国产婷婷成人久久Av免费高清