کانال تلگرام

مدیریت استثناها در سی شارپ

تاریخ : ۲۳ مهر ۱۳۹۸
نویسنده : امیر حسین نصر
دسته بندی ها : آموزشی

برنامه هایی که ما می نویسیم، ممکن است گاهی اوقات دچار مشکل و اشتباه شود. البته در زبان سی شارپ از کامپایلری استفاده می کنیم که بسیار قدرتمند است و در پیدا کردن این خطاها به ما کمک می کند.

img26b

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

using System;
using System.Collections;

namespace ConsoleApplication1
{
    class Program
    {
    static void Main(string[] args)
    {
        int[] numbers = new int[2];

        numbers[0] = 23;
        numbers[1] = 32;
        numbers[2] = 42;

        foreach(int i in numbers)
        Console.WriteLine(i);
        Console.ReadLine();
    }
    }
}

اگر مثال بالا را اجرا کنید، خواهید فهمید که من در مورد چه چیزی صحبت می کنم. آیا در حین اجرا با مشکل مواجه می شوید؟ در مثال بالا آرایه ای از اعداد صحیح را با ظرفیت دوخانه تعریف کردیم. اما سعی می کنیم در خانه سومی از این آرایه که  وجود ندارد مقداری قرار دهیم.

بدیهی است که این مورد منجر به خطا در زمان اجرا می شود. البته زمانی که از محیط ویژوال استودیو برای اجرای این کد استفاده می کنید، گزینه های مختلفی برای نمایش دلیل خطا در اختیار ما قرار می گیرد. اما اگر سعی کنید برنامه را بدون این محیط و با کلیک کردن بر روی فایل EXE اجرا کنید با خطای ناخوشایندی روبرو می شوید. خوشبختانه می توان این خطاها را مدیریت کرد. در زیر نسخه های تغییر یافته از نمونه مثال را مشاهده می کنید : 

int[] numbers = new int[2];
try
{
    numbers[0] = 23;
    numbers[1] = 32;
    numbers[2] = 42;

    foreach(int i in numbers)
    Console.WriteLine(i);
}
catch
{
    Console.WriteLine("Something went wrong!");
}
Console.ReadLine();

اجازه دهید دوست جدید خود را که در زمان مدیریت خطاها به کمک ما می آید، به شما معرفی کنم. بلاک try..catch . اکنون برنامه بالا را در کامپیوتر خود اجرا کنید و خودتان تفاوت را مشاهده کنید.اکنون بهتر است به جای این که ویژوال استودیو و یا محیط سیستم عامل به ما بگوید یک مشکل جدی داریم، خودمان این خطا را مدیریت کرده و پیغام مناسبی را به کاربر نشان دهیم.

در نمونه مثال بالا در زمان ایجاد این خطا به کاربر خود گفته ایم، مشکلی به وجود آمده است. اما بهتر نیست نوع مشکل را مشخص کنیم. بله می توان این کار را هم انجام داد :

catch(Exception ex)
{
    Console.WriteLine("An error occured: " + ex.Message);
}

 همانطور که مشاهده می کنید ما چیزی را به عبارت catch اضافه کرده ایم اکنون می توانیم اعلام کنیم که چه استثنایی رخ داده است. در سی شارپ انواع مختلفی از استثناها وجود دارند که پایه و اساس همه آنها کلاس Exception است. با استفاده از کد بالا توضیحی قابل درک از نوع مشکل ارائه شده است. همانطور که در بالا هم گفته شد Exception عمومی ترین نوع از یک استثنا است.

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

Console.WriteLine("An error occured: " + ex.GetType().ToString());

نتیجه کد بالا چیزی نیست جزاستثنای IndexOutOfRangeException. بنابراین باید این استثنا را به بهترین وجه کنترل کنیم اما هیچ چیز ما را در کنترل انواع استثناها محدود نمی کند. ممکن است در برخی مواقع کارهای مختلفی انجام دهید، برای مثال می توان به شکل زیر عمل کرد :

catch(IndexOutOfRangeException ex)
{
    Console.WriteLine("An index was out of range!");
}
catch(Exception ex)
{
    Console.WriteLine("Some sort of error occured: " + ex.Message);
}

همانطور که می بینید در ابتدا به دنبال استثنای IndexOutOfRangeException میگردیم. البته می‌توانستیم به روشی دیگر عمل کنیم. بلاک جایگزین catch به همراه کلاس Exception می‌توانست برای ما این کار را انجام دهد، زیرا همه استثنا ها از این کلاس مشتق می شوند. با این حال همیشه بهتر است استثناهای خاص‌تر را در ابتدا بنویسیم.

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

البته با توجه به این که نمونه مثال هایی که در این مقاله آورده ایم بسیار ساده است.، به هیچ گونه تمیزکاری نیاز نداریم با این حال در نمونه مثال زیر بلاک جایگزین گنجانده شده است :

int[] numbers = new int[2];
try
{
    numbers[0] = 23;
    numbers[1] = 32;
    numbers[2] = 42;

    foreach(int i in numbers)
    Console.WriteLine(i);
}
catch(IndexOutOfRangeException ex)
{
    Console.WriteLine("An index was out of range!");
}
catch(Exception ex)
{
    Console.WriteLine("Some sort of error occured: " + ex.Message);
}
finally
{
    Console.WriteLine("It's the end of our try block. Time to clean up!");
}
Console.ReadLine();

اگر کد فوق را اجرا کنید خواهید دید که هم بلاک های های استثنا و هم بلاک finally اجرا می‌شود. نکته مهم دیگری که باید بدانید این است که کدهایی که بعد از وقوع استثنا قرار می‌گیرند اجرا نخواهند شد. در نمونه مثال بالا بعد از وقوع استثنا و اجرا شدن بلاک های های مربوطه تنها خط ()Console.ReadLine اجرا خواهد شد و  کامپایلر هیچگاه به حلقه foreach نخواهد رسید 

#استثنا #استثناها_در_سی_شارپ
۰ نظر

مقالات پیشنهادی

مشاهده همه مقالات
ثبت دیدگاه

برای ارسال دیدگاه لازم است ابتدا وارد سایت شوید