استثناها و مدیریت خطاها در #C
در زبان #C، مدیریت خطاها و استثناها از طریق مکانیزم استثنا (Exception Handling) انجام میشود. هدف از مدیریت استثناها، جلوگیری از کرش کردن برنامه و ارائه یک روش ساختارمند برای پاسخ به خطاها و مشکلاتی است که ممکن است در زمان اجرا رخ دهند. این کار با استفاده از دستورات try, catch, finally انجام میشود.
۱. مفهوم استثنا (Exception)
استثناها در واقع خطاهایی هستند که در حین اجرای برنامه رخ میدهند و برنامه را از روند طبیعی خود خارج میکنند. این خطاها میتوانند به دلایل مختلفی مانند ورودی نادرست، دسترسی به منابع غیرمجاز، یا مشکلات در ارتباط با پایگاه داده پیش آیند.
در #C، هنگامی که یک استثنا رخ میدهد، میتوان آن را بهطور خاص مدیریت کرد تا برنامه بدون متوقف شدن یا کرش کردن، ادامه یابد.
۲. دستورات try, catch, finally
#C از سه دستور اصلی برای مدیریت استثناها استفاده میکند:
- try: کدی که ممکن است باعث بروز استثنا شود داخل بلاک try قرار میگیرد.
- catch: اگر استثنایی در بلاک try رخ دهد، این بخش برای مدیریت و پردازش استثنا اجرا میشود.
- finally: کدی که در هر صورت (چه استثنا رخ دهد چه ندهد) اجرا میشود. این معمولاً برای آزاد کردن منابع یا انجام کارهای نهایی استفاده میشود.
۳. نحوه استفاده از try, catch, finally
class Program
{
static void Main()
{
try
{
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers[5]); // خطا: دسترسی به ایندکس نامعتبر
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("خطا: " + ex.Message); // مدیریت خطا
}
finally
{
Console.WriteLine("این بخش همیشه اجرا میشود.");
}
}
}
خروجی:
این بخش همیشه اجرا میشود.
در این مثال، کدی که ممکن است خطا ایجاد کند در بلاک try قرار دارد. اگر استثنا بهوجود آید، بلاک catch آن را مدیریت میکند. بلاک finally در هر صورت (حتی اگر خطا رخ ندهد) اجرا میشود.
۴. چندین بلاک catch
در #C میتوان از چندین بلاک catch استفاده کرد تا انواع مختلف استثناها را مدیریت کرد. هر بلاک catch میتواند نوع خاصی از استثنا را مدیریت کند.
مثال از چندین بلاک catch
class Program
{
static void Main()
{
try
{
int x = 10;
int y = 0;
int result = x / y; // خطا: تقسیم بر صفر
}
catch (DivideByZeroException ex)
{
Console.WriteLine("خطا: تقسیم بر صفر.");
}
catch (Exception ex)
{
Console.WriteLine("یک خطای عمومی رخ داد: " + ex.Message);
}
}
}
خروجی:
در این مثال، ابتدا یک بلاک catch برای استثنای DivideByZeroException وجود دارد و اگر استثنای دیگری رخ دهد، بلاک catch بعدی آن را مدیریت خواهد کرد.
۵. استفاده از throw برای پرتاب استثنا
در بعضی مواقع، ممکن است بخواهید استثنایی را خودتان پرتاب کنید (یعنی استثنا را ایجاد کنید). این کار با استفاده از کلمهکلیدی throw انجام میشود.
مثال از استفاده از throw
class Program
{
static void Main()
{
try
{
ValidateAge(-5); // پرتاب استثنا برای سن نامعتبر
}
catch (ArgumentException ex)
{
Console.WriteLine("خطا: " + ex.Message);
}
}
static void ValidateAge(int age)
{
if (age < 0)
{
throw new ArgumentException("سن نمیتواند منفی باشد.");
}
Console.WriteLine("سن معتبر است.");
}
}
خروجی:
در این مثال، متد ValidateAge یک استثنا را با استفاده از throw پرتاب میکند اگر مقدار سن منفی باشد. سپس این استثنا در بلاک catch مدیریت میشود.
۶. استثناهای سفارشی
در #C میتوان استثناهای سفارشی (Custom Exceptions) ایجاد کرد که ممکن است به برنامهنویسان برای مدیریت خطاهای خاص کمک کنند.
مثال از استثناهای سفارشی
class InvalidAgeException : Exception
{
public InvalidAgeException(string message) : base(message)
{
}
}
class Program
{
static void Main()
{
try
{
ValidateAge(-10);
}
catch (InvalidAgeException ex)
{
Console.WriteLine("خطای سفارشی: " + ex.Message);
}
}
static void ValidateAge(int age)
{
if (age < 0)
{
throw new InvalidAgeException("سن نمیتواند منفی باشد.");
}
}
}
خروجی:
در این مثال، یک استثنای سفارشی به نام InvalidAgeException ایجاد شده است که در صورت وقوع خطای خاصی، این استثنا پرتاب میشود.
۷. بررسی چند استثنا بهطور همزمان (Exception Filtering)
در C# 6.0 به بعد، میتوان از ویژگی فیلتر استثنا (Exception Filtering) استفاده کرد تا استثناها را با توجه به شرایط خاصی فیلتر کرد.
مثال از فیلتر استثنا
class Program
{
static void Main()
{
try
{
int x = 10;
int y = 0;
int result = x / y; // خطا: تقسیم بر صفر
}
catch (DivideByZeroException ex) when (ex.Message.Contains("divide"))
{
Console.WriteLine("یک خطای تقسیم بر صفر رخ داد.");
}
}
}
خروجی:
با استفاده از عبارت when میتوان فیلترهایی را برای مدیریت استثنا اعمال کرد. در اینجا، فقط استثنای DivideByZeroException که پیامی با عبارت "divide" دارد، مدیریت میشود.
جمعبندی
مدیریت استثناها در #C یک روش ساختارمند برای پاسخ به خطاها و مشکلات احتمالی در زمان اجرای برنامه است. از طریق دستورات try, catch, finally میتوان به راحتی استثناها را مدیریت کرد و از کرش کردن برنامه جلوگیری کرد. همچنین، امکان پرتاب استثناهای سفارشی و استفاده از فیلتر استثنا به برنامهنویس اجازه میدهد که مدیریت خطاها را دقیقتر و انعطافپذیرتر انجام دهد.
