Bagikan melalui


Penanganan Pengecualian (Panduan Pemrograman C#)

Blok try digunakan oleh pemrogram C# untuk mempartisi kode yang mungkin terpengaruh oleh pengecualian. Blok catch terkait digunakan untuk menangani pengecualian apa pun yang dihasilkan. Blok finally berisi kode yang dijalankan terlepas dari apakah pengecualian dilemparkan ke dalam blok try atau tidak, seperti melepaskan sumber daya yang dialokasikan di blok try. Suatu blok try memerlukan satu atau lebih catch blok yang terkait, atau satu blok finally, atau keduanya.

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

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 finally menyebabkan kesalahan kompilator.

Menangkap Blok

Blok catch dapat menentukan jenis pengecualian untuk ditangkap. Spesifikasi jenis disebut filter pengecualian . Jenis pengecualian harus diturunkan 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. catch Blok akan dievaluasi dari atas ke bawah dalam kode Anda, tetapi hanya satu blok catch yang dijalankan untuk setiap pengecualian yang dilemparkan. catch Blok pertama, yang menentukan jenis yang tepat atau kelas dasar dari pengecualian yang dilempar, telah dijalankan. Jika tidak ada blok catch yang menentukan kelas pengecualian yang cocok, maka blok catch yang tidak memiliki jenis apa pun akan dipilih, jika ada dalam pernyataan. Penting untuk memposisikan catch blok dengan kelas pengecualian paling spesifik (yaitu, yang paling diturunkan) terlebih dahulu.

Menangkap 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 objek FileNotFoundException.
  • 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 menambahkan entri ke log kesalahan sebelum memunculkan kembali 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 klausul tangkapan. Filter pengecualian menunjukkan bahwa klausul tangkapan tertentu hanya cocok jika kondisi itu benar. Dalam contoh berikut, kedua klausul tangkapan menggunakan kelas pengecualian yang sama, tetapi kondisi tambahan perlu 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 kembali false dapat digunakan untuk memeriksa seluruh pengecualian tetapi tidak memprosesnya. Penggunaan tipikal 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;
    }
}

Metodenya LogException selalu kembali false, tidak ada klausul catch yang menggunakan filter pengecualian ini yang memiliki kecocokan. Klausul tangkapan dapat bersifat umum, menggunakan System.Exception, dan klausul selanjutnya dapat memproses kelas pengecualian yang lebih spesifik.

Akhirnya Blok

Blok finally memungkinkan Anda untuk membersihkan tindakan yang dilakukan di blok try. Jika ada, blok finally dieksekusi terakhir, setelah blok try maupun blok catch apa pun yang cocok. Blok finally selalu berjalan, baik pengecualian dilempar atau blok catch yang cocok dengan jenis pengecualian telah ditemukan.

Blok finally dapat digunakan untuk melepaskan sumber daya seperti aliran file, koneksi basis data, dan pegangan grafik tanpa menunggu pengumpul sampah selama waktu berjalan untuk menyelesaikan objek.

Dalam contoh berikut, blok finally digunakan untuk menutup file yang dibuka di blok try. Perhatikan bahwa status pegangan file akan diperiksa sebelum file ditutup. Jika blok try tidak dapat membuka file, pegangan file masih memiliki nilai null dan blok finally tidak mencoba untuk menutupnya. Sebaliknya, jika file berhasil dibuka di blok try, blok finally akan 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 lebih lanjut, lihat Pengecualian dan Pernyataan try dalam Spesifikasi Bahasa C# . Spesifikasi bahasa adalah sumber definitif untuk sintaks dan penggunaan C#.

Lihat juga