ایران سرفراز- نرم افزار وپروژهای دانشجویی


نرم افزار وپروژهای دانشجویی

فصل نوزدهم اداره کردن استثناء در #C

<!-- /* Font Definitions */ @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:-1610611985 1107304683 0 0 159 0;} @font-face {font-family:Tahoma; panose-1:2 11 6 4 3 5 4 4 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:1627400839 -2147483648 8 0 66047 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"Times New Roman","serif"; mso-fareast-font-family:"Times New Roman";} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; font-size:10.0pt; mso-ansi-font-size:10.0pt; mso-bidi-font-size:10.0pt;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:35.4pt; mso-footer-margin:35.4pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->

فصل نوزدهم

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

آنچه که در این فصل یاد خواهید گرفت:

با مفهوم استثناء و نحو هی مدیریت آن توسط سیتم عامل آشنا خواهید شد.

با نحوه ی کنترل استثناءهای برنامه توسط برنام هنویس آشنا خواهید شد.

را برای اداره کردن استثنا/ئ به کار خواهید برد. try/catch/finally • ساختار

پیش بینی نشده است ایجاد خواهید کرد. NET. • استثناءهای سفارشی جهت تولید پیام های مناسبی که در

-1-19 مقدمه

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

خاتمه ندهد. بدین معنی که باید یک برنامه با خطاهای زمان اجرا بصورت مطلوب رفتار نماید. اینکه آنها از خطای کد برنامه

یا خطاهای سختافزاری نشأت میگیرند. (FCL)

1 به منظور برخورد با شرایط خطا برای توسعهدهندگان (SEH) یک تکنیک بنام اداره کردن ساختیافتهی استثناء NET.

فراهم میسازد. هدف اصلی این است که،زمانی که یک استثناء رخ میدهد، یک شی استثناء ایجاد شده و کنترل برنامه به

شی استثناء از یک بخش به بخش دیگر که آن را درک میکند، منتقل ،NET. بخش خاصی از کد رد میشود. در اصطلاحات

میشود.

مزایای SEH ، در مقایسه با تکنیکهای اداره کردن خطا، که به کدهای خطا استناد میکنند و مقادیر بیتی را تنظیم میکنند

مهمی را پیشنهاد میکند:

استثناء همانند یک شی به برنامه رد میشود. خصوصیات آن، یک توصیف از استثناء، نام اسمبلی که استثناء را رد 􀂙

کرده است، مقداری از پشته که نشان دهنده دنبالهی فراخوانیهای منجر شده به این استثناء هستند، را شامل

میشوند.

برنامه را خاتمه میدهد. این عمل توسعه CLR ، اگر یک استثناء به برنامه رد شود و برنامه نتواند آن را درک کند 􀂙

دهنده را به اداره کردن خطا مجبور میسازد.

لازم نیست کد تشخیص و ادارهی استثناء در محل رخ دادن خطا قرار گیرد. بدین معنی که، کد اداره کردن استثناء 􀂙

میتواند در یک کلاس خاص مختص یافته به آن خطا قرار گیرد.

1 Structured exception handling

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

326

،NET. استثناها در هر دو سطح برنامه و سیستم بطور سازگار و انحصاری استفاده میشوند. همه متدهای چارچوب 􀂙

زمانی که یک خطا رخ دهد استثناء رد میکنند.

قبل از مشاهد ه مکانیزم های واقعی پیاد هسازی اداره کردن استثناء، اجازه دهید خود استثناء را بررسی کنیم. همانطور که قبلاً

مشتق می شوند. پس فهم System.Exception از کلاس NET. شرح دادیم. استثناء یک کلاس است. همه استثناهای

این کلاس برای کار با استثناها ضروری است.

System.Exception -2-19 کلاس

کلاس پایه برای دو زیر کلاس کلی System.Exception . 1 نمایش داده شده اس ت - همانطور که در شکل 19

است که همه اشیاء استثناء از آنها ار ث بری م یکنند. ApplicationException و SystemException

مستقیماً از ( ArithmticException و IOException همچون )NET. استثناهای چارچوب

ApplicationException مشتق م یشوند، در حالی که استثناهای سفارشی برنامه از SystemException

ارث بری می کنند. تنها هدف این کلا س ها گرو ه بندی استثناهاس ت . چون آنها هیچ خصوصیت یا متدی به کلاس

اضافه نمی کنند. System.Exception پایه ی

1- شکل 19

1 اعضای این کلاس را خلاصه م یکند. - چند تا عضو دارد. جدول 19 System.Exception کلاس

1- جدول 19

خصوصیت نوع توصیف

که به مستندات کمکی اشاره می کند. URL یک String HelpLink

دارد، مگر اینکه استثناء در هنگام اداره کردن استثناء null مقدار Exception InnerException

م ی توان زنجیر ه ی GetBaseException دیگر رخ ده د . با متد

استثناهای تودرتو را یافت.

متنی که استثناء را شرح می دهد. String Message

نام اسمبلی که استثناء را تولید کرده است. String Source

دنباله ای از اسامی و نشان ه ی متدها که قبل از استثناء فراخوانی String StackTrace

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

جرئیاتی در مورد متدی که استثناء را رد کرده است فراهم م ی کند . MethodBase TargetSite

نام متدی که استثناء در آن اتفاق افتاده است را بر م ی گرداند . آن

فصل نوزدهم اداره کردن استثناها

327

دارد که نام کلاس مربوط به DeclaringType یک خصوصیت بنام

متد را بر می گرداند.

استفاده Com این خصوصیت محافظت شده در زمان کار با کد Int32 HResult

رد Com می شود. زمانی که یک استثنا به یک سروی س گیرنده ی

در دنیای کد مدیریت نشده HResult می شود، این مقدار به یک

تبدیل می گردد.

-3-19 کدنویسی برای اداره کردن استثناها

2) به کار م یبرد. - برای پیاده سازی اداره کردن استثناء (شکل 19 try/catch/finally یک ساختار #C

ی را جستجو م ی کند که م ی تواند استثناء جاری را اداره catch زمانی که یک استثناء رخ م ی دهد، سیستم بلوک

موجود در متد catch کند. آن جستجو را از متد جاری شروع م یکند و اگر پیدا نشود لیست بلو کهای

منطبق را پیدا نکند یک استثناء اداره catch فراخواننده ی این متد را جستجو م ی کند، اگر عمل جستجو بلوک

نشده رخ م ی دهد . همانطور که بعداً بررسی خواهیم کرد، برنامه کاربردی مسئول تعریف یک سیاست برای

برخورد با این استثناها است. به جزئیات کاربرد این سه بلوک توجه کنید.

2- شکل 19

try بلوک

را برای اداره finally یا Catch کد داخل این بلوک را ناحی ه ی محفظ می گویند، چون آن ناحیه بلو ک های

finally یا catch باید حداقل یک بلوک try کردن استثناهای ممکن یا حذف عوارض جانبی دارن د . هر بلوک

مرتبط با آن داشته باشد.

catch بلوک

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

328

و به دنبال آن در داخل پرانتزه  ا یک عبارت به نام فیلتر استثناء را catch کلم ه ی کلیدی ،Catch یک بلوک

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

را پیاده سازی می کند.

فیلتر استثناء، استثنائی که آن اداره م ی کند را تعریف م ی کند و زمانی که یک استثناء به آن پاس داده م ی شود

آنرا بصورت یک پارامتر به کار می گیرد. دستور زیر را ملاحظه کنید.

Catch (Divide By zero ex) {…..} Exception

به استثناء ex رخ دهد، این فیلتر احضار م ی شود. متغیر System.DivideByZeroException اگر یک

ex.StackTrace و ex.Message ارجاع می کند و دسترسی به خصوصیات آنرا فراهم م یسازد. همچون

بکار م ی برید، ترتیب مهم اس ت . آنها باید بصورت سلسله مراتبی لیست شون د . که catch زمانی که چندین بلاک

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

کامپایلر یک خطا تولید می کند.

{..…} ( Catch(Divide By zero Exception ex

{.....} (Catch ( Index out of Range Exception ex

{.....} ( Catch (Exception ex

این کد ابتدا استثناء تقسیم بر صفر یا اندیس خارج از محدوده را جستجو م ی کند . فیلتر استثناء آخری (

را پاس می کند. System.Exception هر استثناء مشتق شده از ( Exception

پرش م ی شود . اگر بلوک catch زمانی که یک استثناء رخ دهد، کد این بلوک اجرا م ی شود و از بقیه بلو ک های

وجود داشته باشد کنترل برنامه به آن جریان م ییابد. finally

برای پاس کردن استثناء به متد فراخوانی کننده در بالای throw یک دستور catch توجه: ممکن است بلوک

یک پارامتر اختیاری در داخل پرانتزها دارد که نوع استثناء پاس شده را throw پشته داشته باش د. دستور

بدون پارامتر استفاده شود، استثناء در همین متد پاس م یشو د. زمانی که متد throw مشخص م یکند اگر

فراخوانی کننده برای اداره کردن استثناء بهتر باشد، یک استثناء را به آن پاس م یکنند.

finally بلوک

اجرا م ی شود .خواه استثناء رخ دهد، خواه رخ finally به عنوان یک بلوک تصفیه در نظر گرفته م ی شود . بلوک

ندهد. آن محل مناسبی برای انجام عملیات تصفیه همچون بستن فایل و اتصالات پایگا ه داده اس ت . اگر بلوک

نداشته باشیم، این بلوک ضروری است در غیر این صورت اختیاری است. catch

System.Exception مثال اداره کردن استثنا های عمومی

نشان CLR را در برخورد با یک استثناء تولید شده توسط try/catch/finally 1 بلوک های - مثال 19

می دهد.

1- مثال 19

Listing 4-2using System;

// Class to illustrate results of division by zero

public class TestExcep

{

فصل نوزدهم اداره کردن استثناها

329

public static int Calc(int j)

{

return (١٠٠ / j);

}

}

class MyApp

{

public static void Main()

{

TestExcep exTest = new TestExcep();

try

{

// Create divide by zero in called method

int dZero = TestExcep.Calc(٠);

// This statement is not executed

Console.WriteLine("Result: {٠}",dZero);

}

catch(DivideByZeroException ex)

{

Console.WriteLine("{٠}\n{١}\n", ex.Message, ex.Source);

Console.WriteLine(ex.TargetSite.ToString());

Console.WriteLine(ex.StackTrace);

}

catch (Exception ex)

{

Console.WriteLine("General "+ex.Message);

}

finally

{

Console.WriteLine("Cleanup occurs here.");

}

}

}

یک استثناء تقسیم بر صفر پاس م یکند، زمانی که آن را با مقدار صفر TestExcep.Calc در این مثال

هیچ کدی برای اداره کردن استثناء ندارد، به طور اتوماتیک به نقطه فراخوانی Calc فراخوانی می کنیم. چون

پاس داده می شود و در آنجا، کنترل برنامه به بلوک اداره کردن استثناء MyApp در Calc

اطلاعات زیر را نمایش catch جریان م ییابد. برای نمونه، دستورات بلوک DivideByZeroException

می دهد.

خصوصیت مقدار داخل آن

Attempted to divide By Zero Ex.Message

Zeroexcept Ex.Source

()void Main ex.TargetSite

()at MyApp .Main ex.StackTrace

-4-19 چگونه یک کلاس استثناء سفارشی ایجاد کنیم؟

زمانی که شما نیاز دارید خطاهای منتشر شده توسط ک  لاس ها را شرح دهید، کلا س های استثناء سفارشی مفید

هستند. برای مثال، ممکن است بخواهید استثناء مربوط به رفتار خاص خطاساز را شرح دهید یا مشکل یک

اسلام احمد زاده - 09177112161 - C# برنامهنویسی

330

پارامتر را مشخص کنید که شرایطی را رعایت نکرده است. در کل، استثناءهای سیستمی خاص در دسترس

هستند. اگر کافی نیستند، می توانید کلا سهای خاص خودتان را ایجاد کنید.

2 اگر شی هر دو واسط مورد نیاز را پیاد ه سازی نکند، متد یک استثناء سفارشی تولید م ی کند . - در مثال 19

یک پیام بر می گرداند که خطا و نام شی خطاساز را شرح م یدهد. NoDescException استثناء

2- مثال 19

// Custom Exception Class

[Serializable]

public class NoDescException : ApplicationException

{ // Three constructors should be implemented

public NoDescException(){}

public NoDescException(string message):base(message){}

public NoDescException(string message, Exception innerEx)

:base(message, innerEx){ }

}

// Interfaces that shape objects are to implement

public interface IShapeFunction

{ double GetArea(); }

public interface IShapeDescription

{ string ShowMe();}

// Circle and Rectangle classes are defined

class Circle : IShapeFunction

{

private double radius;

public Circle (double rad)

{

radius= rad;

}

// Methods to implement both interfaces

public double GetArea()

{ return (٣٫١۴*radius*radius); }

}

class Rectangle : IShapeFunction, IShapeDescription

{

private int width, height;

public Rectangle(int w, int h)

{

width= w;

height=h;

}

// Methods to implement both interfaces

public double GetArea()

{ return (height*width); }

public string ShowMe()

{ return("rectangle"); }

}

public class ObjAreas

{

public static void ShowAreas(object ObjShape)

{

// Check to see if interfaces are implemented

if (!(ObjShape is IShapeDescription &&

ObjShape is IShapeFunction) )

{

// Throw custom exception

string objName = ObjShape.ToString();

throw new NoDescException

("Interface not implemented for "+objName);

}

// Continue processing since interfaces exist

IShapeFunction myShape = (IShapeFunction)ObjShape;

فصل نوزدهم اداره کردن استثناها

331

IShapeDescription myDesc = (IShapeDescription) ObjShape;

string desc = myDesc.ShowMe();

Console.WriteLine(desc+" Area= "+

myShape.GetArea().ToString());

}

}

ایجاد کنید و آنها را به عنوان پارامتر به متد ایستای shape برای ____________دیدن عملی استثناء سفارشی، دو شی

ارسال کنید. ObjAreas.ShowAreas

static ObjAreas.ShowAreas method.

Circle myCircle = new Circle(4,,0);

Rectangle myRect = new Rectangle(5،2);

try

{

ObjAreas.ShowAreas(myRect);

ObjAreas.ShowAreas(myCircle);

}

catch (NoDescException ex)

{

Console.WriteLine(ex.Message);

}

بررسی م ی کند تا مطمئن شود شی مربوط به آن، هر دو واسط را پیاد ه سازی م ی کند . در غیر ShowAreas متد

پاس م یدهد و کنترل را به کد فراخوانی کننده رد NoDescException اینصورت، آن یک نمونه از استثناء

فقط یک واسط پیاده سازی می کند، در نتیجه یک استثناء رخ م یدهد. Circle می کند. در این مثال، شی

توجه کنی د . آن یک مدل مفید است که قوانین پیاد ه سازی یک نوع استثناء NoDescException به طراحی

سفارشی را نشان می دهد:

مشتق شود. ApplicationException • باید کلاس استثناء از

سه Exception باشد. کلاس پایه Exception • بر اساس قرارداد، در انتهای نام استثناء کلم ه ی

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

-1 یک سازنده با پرانتز خالی که به عنوان پیش فرض است.

دارد. Message -2 سازنده ای با یک پارامتر، رشته ای که معمولاً نام

زمانی که یک استثناء در حین اداره ،Exception -3 سازنده ای با یک پارامتر رشت ه ای و یک پارامتر از نوع

کردن استثناء دیگر رخ دهد بکار می رود.

را در ایجاد شی بکار بری د . اگر م ی خواهید خصوص ی ات یا فیلدهایی را اضافه کنید، base + مقدار دهنده اولیه

یک سازنده جدید برای این مقادیر ایجاد کنید.

برای اهداف xml برای تعیین ترتیبی بودن استثناء اس ت . یعنی آن م ی تواند بصورت serializable + صفت

ذخیره و انتقال نمایش داده شو د . می توان از آن صرفنظر کرد، چون فقط زمانی لازم است که یک اس ت ثناء از کد

مربوط به دامنه کاربردی دیگر پاس داده شود.

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

332

-5-19 استثناءهای اداره نشده

مرتبط با یک استثناء را پیدا کند، استثناءهای اداره نشده رخ م ی دهد . نتیجه catch نتواتد بلوک CLR زمانی که

آن را با متدهای خود اداره می کند. CLR ، پیش فرض اینکه

اگرچه آن یک هشدار ب ر ای کاربر یا توسعه دهنده فراهم م ی کند، ولی هیچ راهی برای برخورد با آن توصیه

برای جمع کردن ،NET نمی کند. راه حل مسئله این است که از مزیت اداره کنند ه های رویداد استثناء اداره نشده

همه آنها به کلاس اداره کننده استثناء سفارشی خود استفاده کنید.

کلاس سفارشی یک روش مطلوب برای بنا کردن یک سیاست برخورد با استثناءهای اداره نشده فراهم می کند.

 

 

 

 

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

 

 

   + MOHSEN GHASEMI - ٩:٢۱ ‎ق.ظ ; ۱۳۸٩/٤/٢٤