C# xử lý lỗi bằng exception được bắt qua try/catch/finally. Xử lý exception đúng nghĩa là bắt các kiểu exception cụ thể, dọn dẹp tài nguyên (thường với using), tạo các custom exception có ý nghĩa, và không nuốt lỗi một cách âm thầm.
C# xử lý lỗi bằng exception được bắt qua try/catch/finally. Xử lý exception đúng nghĩa là bắt các kiểu exception cụ thể, dọn dẹp tài nguyên (thường với using), tạo các custom exception có ý nghĩa, và không nuốt lỗi một cách âm thầm.
try
{
var data = RiskyOperation();
}
catch (FileNotFoundException ex) // bắt các kiểu CỤ THỂ (cụ thể nhất trước)
{
Console.WriteLine($"File missing: {ex.Message}");
}
catch (IOException ex)
{
Log(ex);
throw; // ném lại, GIỮ NGUYÊN stack trace (không phải `throw ex`)
}
catch (Exception ex) // bắt tất cả (cuối cùng) — gốc của mọi exception
{
Log(ex);
}
finally
{
Cleanup(); // LUÔN chạy (thành công, exception, hoặc return)
}
Bắt các kiểu exception cụ thể trước, dùng Exception làm bắt-tất-cả cuối cùng, và finally cho việc dọn dẹp luôn phải chạy. Quan trọng: dùng throw; (không phải throw ex;) để ném lại — nó giữ nguyên stack trace gốc.
if (amount < 0)
throw new ArgumentException("Amount must be positive", nameof(amount));
// một custom exception cho domain của bạn
public class InsufficientFundsException : Exception
{
public InsufficientFundsException(string message) : base(message) { }
}
throw new InsufficientFundsException("Balance too low");
// `using` đảm bảo Dispose() được gọi (đóng file/connection) ngay cả khi có exception
using (var file = new StreamReader("data.txt"))
{
var content = file.ReadToEnd();
} // file.Dispose() được gọi tự động tại đây
using var conn = new SqlConnection(...); // dạng giản lược C# 8
Câu lệnh using đảm bảo các tài nguyên IDisposable (file, connection) được dispose đúng cách — cách được ưa chuộng để xử lý dọn dẹp tài nguyên, đáng tin cậy hơn finally thủ công.
catch (Exception ex) when (ex.Message.Contains("timeout")) // exception filter (when)
{ ... }
✓ Bắt exception CỤ THỂ, không chỉ Exception
✓ Dùng `using` cho tài nguyên IDisposable (dọn dẹp đáng tin cậy)
✓ Đừng nuốt exception âm thầm (catch rỗng) — log hoặc ném lại
✓ Dùng `throw;` (không phải `throw ex;`) để giữ nguyên stack trace
✓ Tạo custom exception có ý nghĩa; đừng dùng exception cho luồng điều khiển thông thường
Xử lý exception đúng là thiết yếu để xây dựng các ứng dụng C# vững chắc, đáng tin cậy, nên hiểu nó kỹ lưỡng là quan trọng.
Cấu trúc try/catch/finally, bắt các kiểu exception cụ thể (để xử lý có mục tiêu) với Exception làm bắt-tất-cả cuối cùng, và finally cho việc dọn dẹp được đảm bảo là điều cơ bản.
Một số thực hành tốt đặc thù của C# đặc biệt quan trọng: dùng throw; thay vì throw ex; khi ném lại (một chi tiết tinh tế nhưng then chốt — throw ex; reset stack trace, làm mất thông tin debug quý giá), dùng câu lệnh using cho tài nguyên IDisposable (cách được ưa chuộng, đáng tin cậy để đảm bảo file, connection và các tài nguyên khác được dọn dẹp đúng ngay cả khi có exception — vững chắc hơn các khối finally thủ công, và là trung tâm của mô hình quản lý tài nguyên của C#), và không nuốt exception âm thầm.
Hiểu xử lý exception — cấu trúc, bắt cụ thể, custom exception, ném lại giữ nguyên stack trace, và đặc biệt là using cho dọn dẹp tài nguyên — là quan trọng để viết C# đáng tin cậy xử lý lỗi một cách duyên dáng và quản lý tài nguyên đúng cách.
Vì exception không xử lý và rò rỉ tài nguyên gây ra các vấn đề độ tin cậy thực, và vì C# có các thành ngữ cụ thể (mẫu using, giữ nguyên throw;) phân biệt code vững chắc với code mong manh, làm chủ xử lý exception là kiến thức quan trọng, thường xuyên áp dụng để phát triển C# chuyên nghiệp.
Thư viện câu hỏi phỏng vấn IT với đáp án chi tiết — từ Junior đến Senior.
Ủng hộ