Bagikan melalui


Penanganan Pengecualian (Panduan Pemrograman C#)

Blok coba digunakan oleh pemrogram C# untuk mempartisi kode yang mungkin dipengaruhi oleh pengecualian. Blok catch terkait digunakan untuk menangani pengecualian yang dihasilkan. Blok finally berisi kode yang dijalankan terlepas dari apakah pengecualian dilemparkan dalam blok try atau tidak, seperti merilis sumber daya yang dialokasikan di blok try. Blok try memerlukan satu atau beberapa blok terkait catch , atau finally blok, atau keduanya.

Contoh berikut menunjukkan try-catch pernyataan, try-finally pernyataan, dan try-catch-finally pernyataan.

try
{
    // Code to try goes here.
}
catch (SomeSpecificException ex)
{
    // Code to handle the exception goes here.
    // Only catch exceptions that you know how to handle.
    // Never catch base class System.Exception without
    // rethrowing it at the end of the catch block.
}
try
{
    // Code to try goes here.
}
finally
{
    // Code to execute after the try block goes here.
}
try
{
    // Code to try goes here.
}
catch (SomeSpecificException ex)
{
    // Code to handle the exception goes here.
}
finally
{
    // Code to execute after the try (and possibly catch) blocks
    // goes here.
}

Blok try tanpa blok catch atau blok finally menyebabkan kesalahan pengkompilasi.

Blok Penanganan

Blok catch dapat menentukan jenis pengecualian yang akan ditangkap. Spesifikasi jenis disebut filter pengecualian. Jenis pengecualian harus berasal dari Exception. Secara umum, jangan tentukan Exception sebagai filter pengecualian kecuali Anda tahu cara menangani semua pengecualian yang mungkin dilemparkan dalam try blok, atau Anda telah menyertakan throw pernyataan di akhir blok Anda catch .

Beberapa catch blok dengan kelas pengecualian yang berbeda dapat dirangkai bersama-sama. Blok catch dievaluasi dari atas ke bawah dalam kode Anda, tetapi hanya satu catch blok yang dijalankan untuk setiap pengecualian yang dilemparkan. Blok pertama catch yang menentukan jenis yang tepat atau kelas dasar pengecualian yang dilemparkan dijalankan. Jika tidak ada catch blok yang menentukan kelas pengecualian yang cocok, catch blok yang tidak memiliki jenis apa pun dipilih, jika ada dalam pernyataan. Penting untuk memposisikan catch blok dengan kelas pengecualian yang paling spesifik (yaitu, yang paling turunan) terlebih dahulu.

Tangkap pengecualian ketika kondisi berikut ini benar:

  • Anda memiliki pemahaman yang baik tentang mengapa pengecualian mungkin dilemparkan, dan Anda dapat menerapkan pemulihan tertentu, seperti meminta pengguna untuk memasukkan nama file baru saat Anda menangkap FileNotFoundException objek.
  • Anda dapat membuat dan melempar pengecualian baru yang lebih spesifik.
    int GetInt(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch (IndexOutOfRangeException e)
        {
            throw new ArgumentOutOfRangeException(
                "Parameter index is out of range.", e);
        }
    }
    
  • Anda ingin menangani sebagian pengecualian sebelum meneruskannya untuk penanganan lebih lanjut. Dalam contoh berikut, blok catch digunakan untuk memasukkan entri ke dalam log kesalahan sebelum melempar ulang pengecualian.
    try
    {
        // Try to access a resource.
    }
    catch (UnauthorizedAccessException e)
    {
        // Call a custom error logging procedure.
        LogError(e);
        // Re-throw the error.
        throw;
    }
    

Anda juga dapat menentukan filter pengecualian untuk menambahkan ekspresi boolean ke klausa tangkapan. Filter pengecualian menunjukkan bahwa klausa tangkapan tertentu hanya cocok ketika kondisi tersebut benar. Dalam contoh berikut, kedua klausa tangkapan menggunakan kelas pengecualian yang sama, tetapi kondisi tambahan diperiksa untuk membuat pesan kesalahan yang berbeda:

int GetInt(int[] array, int index)
{
    try
    {
        return array[index];
    }
    catch (IndexOutOfRangeException e) when (index < 0) 
    {
        throw new ArgumentOutOfRangeException(
            "Parameter index cannot be negative.", e);
    }
    catch (IndexOutOfRangeException e)
    {
        throw new ArgumentOutOfRangeException(
            "Parameter index cannot be greater than the array size.", e);
    }
}

Filter pengecualian yang selalu ditampilkan false dapat digunakan untuk memeriksa semua pengecualian tetapi tidak memprosesnya. Penggunaan umumnya adalah untuk mencatat pengecualian:

public class ExceptionFilter
{
    public static void Main()
    {
        try
        {
            string? s = null;
            Console.WriteLine(s.Length);
        }
        catch (Exception e) when (LogException(e))
        {
        }
        Console.WriteLine("Exception must have been handled");
    }

    private static bool LogException(Exception e)
    {
        Console.WriteLine($"\tIn the log routine. Caught {e.GetType()}");
        Console.WriteLine($"\tMessage: {e.Message}");
        return false;
    }
}

Metode LogException selalu mengembalikan false, tidak ada klausul catch yang menggunakan filter pengecualian ini cocok. Klausul tangkapan bisa umum, menggunakan System.Exception, dan klausul selanjutnya dapat memproses kelas pengecualian yang lebih spesifik.

Akhirnya Blokir

Blok finally memungkinkan Anda untuk membersihkan tindakan yang dilakukan di dalam blok try. Jika ada, blok finally dijalankan terakhir, setelah blok try dan blok catch yang sesuai. Blok finally selalu dijalankan, baik ketika pengecualian dilemparkan atau ketika blok catch yang cocok dengan jenis pengecualian ditemukan.

finally blok dapat digunakan untuk merilis sumber daya seperti stream file, koneksi database, dan handle grafis tanpa menunggu pengumpul sampah runtime untuk menyelesaikan objek.

Dalam contoh berikut, finally blok digunakan untuk menutup file yang dibuka di try blok. Perhatikan bahwa file handle diperiksa sebelum file ditutup. try Jika blok tidak dapat membuka file, handel file masih memiliki nilai null dan blok finally tidak mencoba menutupnya. Sebaliknya, jika file berhasil dibuka di try blok, finally blok menutup file yang terbuka.

FileStream? file = null;
FileInfo fileinfo = new System.IO.FileInfo("./file.txt");
try
{
    file = fileinfo.OpenWrite();
    file.WriteByte(0xF);
}
finally
{
    // Check for null because OpenWrite might have failed.
    file?.Close();
}

Spesifikasi Bahasa C#

Untuk informasi selengkapnya, lihat Pengecualian dan Pernyataan percobaan dalam Spesifikasi Bahasa C#. Spesifikasi bahasa adalah sumber definitif untuk sintaks dan penggunaan C#.

Lihat juga