سه شنبه ۲۷ شهريور ۱۴۰۳
Tut24 آموزش برنامه نویسی و مجله تخصصی فناوری ورود/عضویت

آموزش سی شارپ - مدیریت استثناءها

استثناء (Exception) مشکلی است که در حین اجرای یک برنامه پیش می‌آید. استثناء C# پاسخی است به شرایط استثنایی که در حین اجرای برنامه به وجود می‌آید، مانند تلاش برای تقسیم بر صفر.

استثناء‌ها یک راه برای انتقال کنترل از یک قسمت از برنامه به قسمت دیگر فراهم می‌کنند. مدیریت استثناء C# بر مبنای چهار کلمه کلیدی انجام می‌شود: try (امتحان کن)، catch (گرفتن)، finally (در هر صورت) و throw (پرتاب کردن).

  • try (امتحان کن) - یک بلوک try  استثناء‌های خاصی که در آن فعال می‌شوند را شناسایی می‌کند. این بلوک توسط یک یا چند بلوک catch دنبال می‌شود.

  • catch (گرفتن) - یک برنامه با استفاده از گرفتن استثناء در جایی از برنامه که می‌خواهید مشکل را مدیریت کنید، استثناء را می گیرد. کلمه کلیدی catch گرفتن یک استثناء را نشان می‌دهد.

  • finally (در هر صورت) - بلوک finally برای اجرای یک مجموعه داده شده از دستورات استفاده می‌شود، بدون توجه به اینکه آیا یک استثناء پرتاب شده است یا نه. به عنوان مثال، اگر یک فایل را باز کنید، باید بسته شود، بدون توجه به اینکه آیا استثناءی بوجود آمده است یا نه.

  • throw (پرتاب کردن) - برنامه زمانی که یک مشکل ظاهر می‌شود، با استفاده از کلمه کلیدی throw یک استثناء پرتاب می‌کند.

نحو

با فرض اینکه یک بلوک یک استثناء را ایجاد کرده است، یک متد با استفاده از ترکیب کلمات کلیدی try و catch یک استثناء را می گیرد. یک بلوک try/catch در اطراف کد قرار می‌گیرد که ممکن است یک استثناء تولید کند. کد درون یک بلوک try/catch به عنوان کد محافظت شده شناخته می‌شود و نحو استفاده از try/catch شبیه مثال زیر است:

try {
   // statements causing exception
} catch( ExceptionName e1 ) {
   // error handling code
} catch( ExceptionName e2 ) {
   // error handling code
} catch( ExceptionName eN ) {
   // error handling code
} finally {
   // statements to be executed
}

می‌توانید چندین دستور catch را برای گرفتن انواع مختلف استثناء‌ها لیست کنید، در صورتی که بلوک try شما در شرایط مختلف بیش از یک استثناء ایجاد کند.

کلاس‌های استثناء در C#

استثناء‌ها در C# توسط کلاس‌ها نمایش داده می‌شوند. کلاس‌های استثناء در C# به طور اصلی به صورت مستقیم یا غیرمستقیم از کلاس System.Exception مشتق می‌شوند. برخی از کلاس‌های استثناء مشتق شده از کلاس System.Exception کلاس‌های System.ApplicationException و System.SystemException هستند.

کلاس System.ApplicationException استثناء‌های تولید شده توسط برنامه‌های کاربردی را پشتیبانی می‌کند. بنابراین استثناء‌های تعریف شده توسط برنامه‌نویسان باید از این کلاس مشتق شوند.

کلاس System.SystemException کلاس پایه برای همه استثناءهای سیستم پیش‌تعریف شده است.

جدول زیر برخی از کلاس‌های استثناء پیش‌تعریف شده مشتق شده از کلاس Sytem.SystemException را نشان می‌دهد −

ردیف کلاس استثناء و توضیحات
۱

System.IO.IOException

بررسی خطاهای ورودی/خروجی (I/O).

۲

System.IndexOutOfRangeException

بررسی خطاهای تولید شده وقتی که یک متد به یک اندیس آرایه خارج از محدوده ارجاع دارد.

۳

System.ArrayTypeMismatchException

بررسی خطاهای تولید شده وقتی که نوع مطابقت ندارد با نوع آرایه.

۴

System.NullReferenceException

بررسی خطاهای تولید شده از ارجاع به یک شیء تهی (null).

۵

System.DivideByZeroException

بررسی خطاهای تولید شده از تقسیم بر صفر.

۶

System.InvalidCastException

بررسی خطاهای تولید شده در زمان تبدیل نوع.

۷

System.OutOfMemoryException

بررسی خطاهای تولید شده از عدم وجود حافظه آزاد کافی.

۸

System.StackOverflowException

بررسی خطاهای تولید شده از سرریزی استک (Stack Overflow).

مدیریت استثناء‌ها

C# یک راه حل ساختارمند برای مدیریت استثناء‌ها در قالب بلوک‌های try و catch ارائه می‌دهد. با استفاده از این بلوک‌ها، دستورهای برنامه‌ی اصلی از دستورهای مدیریت خطا جدا می‌شوند.

این بلوک‌های مدیریت خطا با استفاده از کلمات کلیدی try (امتحان کن)، catch (گرفتن) و finally (در هر صورت) پیاده‌سازی می‌شوند. در زیر نمونه‌ای از پرتاب استثناء در صورت بروز شرط تقسیم بر صفر آورده شده است −

using System;

namespace ErrorHandlingApplication {
   class DivNumbers {
      int result;
      
      DivNumbers() {
         result = 0;
      }
      public void division(int num1, int num2) {
         try {
            result = num1 / num2;
         } catch (DivideByZeroException e) {
            Console.WriteLine("Exception caught: {0}", e);
         } finally {
            Console.WriteLine("Result: {0}", result);
         }
      }
      static void Main(string[] args) {
         DivNumbers d = new DivNumbers();
         d.division(25, 0);
         Console.ReadKey();
      }
   }
}

هنگامی که کد بالا کامپایل و اجرا می شود، نتیجه زیر را ایجاد می کند -

Exception caught: System.DivideByZeroException: Attempted to divide by zero. 
at ...
Result: 0

ایجاد استثناء‌های تعریف شده توسط کاربر

شما همچنین می‌توانید استثناء خود را تعریف کنید. کلاس‌های استثناء تعریف شده توسط کاربر از کلاس Exception مشتق می‌شوند. مثال زیر این موضوع را نشان می‌دهد −

using System;

namespace UserDefinedException {
   class TestTemperature {
      static void Main(string[] args) {
         Temperature temp = new Temperature();
         try {
            temp.showTemp();
         } catch(TempIsZeroException e) {
            Console.WriteLine("TempIsZeroException: {0}", e.Message);
         }
         Console.ReadKey();
      }
   }
}
public class TempIsZeroException: Exception {
   public TempIsZeroException(string message): base(message) {
   }
}
public class Temperature {
   int temperature = 0;
   
   public void showTemp() {
      
      if(temperature == 0) {
         throw (new TempIsZeroException("Zero Temperature found"));
      } else {
         Console.WriteLine("Temperature: {0}", temperature);
      }
   }
}

هنگامی که کد بالا کامپایل و اجرا می شود، نتیجه زیر را ایجاد می کند -

TempIsZeroException: Zero Temperature found

پرتاب اشیاء

شما می‌توانید یک شیء را پرتاب کنید (throw) اگر این شیء به طور مستقیم یا غیرمستقیم از کلاس System.Exception مشتق شده باشد. شما می‌توانید در بلوک catch از دستور throw استفاده کنید تا شیء حاضر را پرتاب کنید به شکل −

Catch(Exception e) {
   ...
   Throw e
}