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#.