ورود کاربران VIP سرزمین دانلود، مرجع دانلود و آموزش رایگان نرم افزار

منوی سایت

سی شارپ

تازه های این بخش :

مقدمه ای بر سی شارپ : قسمت هجدهم

(مربوط به موضوع سی شارپ)

مقدمه ای بر سی شارپ : قسمت هجدهم


مقابله با خطاها در سی شارپ :
EXCEPTION یک خطای زمان اجر است که بدلیل شرایطی غیرنرمال در برنامه ایجاد می شود. در سی شارپ exeption کلاسی است در فضای نام سیستم. شیء ایی از نوع exception بیانگر شرایطی است که سبب رخ دادن خطا در کد شده است. سی شارپ از exception ها به صورتی بسیار شبیه به جاوا و سی پلاس پلاس استفاده می نماید.

دلایلی که باید در برنامه exception handling حتما صورت گیرد به شرح زیر است:
- قابل صرفنظر کردن نیستند و اگر کدی این موضوع را در نظر نگیرد با یک خطای زمان اجرا خاتمه پیدا خواهد کرد.
- سبب مشخص شدن خطا در یک نقطه از برنامه شده و ما را به اصلاح آن سوق می دهد.

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


class A {static void Main() {catch {}}}
TEMP.cs(3,5): error CS1003: Syntax error, 'try' expected

class A {static void Main() {finally {}}}
TEMP.cs(3,5): error CS1003: Syntax error, 'try' expected

class A {static void Main() {try {}}}
TEMP.cs(6,3): error CS1524: Expected catch or finally


بهتر است یک مثال ساده را در این زمینه مرور کنیم:


int a, b = 0 ;
Console.WriteLine( "My program starts " ) ;
try
{
a = 10 / b;
}
catch ( Exception e )
{
Console.WriteLine ( e ) ;
}
Console.WriteLine ( "Remaining program" ) ;
The output of the program is:
My program starts
System.DivideByZeroException: Attempted to divide by zero.
at ConsoleApplication4.Class1.Main(String[] args) in
d:dont deleteconsoleapplication4class1.cs:line 51
Remaining program
 


برنامه شروع به اجرا می کند. سپس وارد بلوک و یا قطعه ی try می گردد. اگر هیچ خطایی هنگام اجرای دستورات داخل آن رخ ندهد ، برنامه به خط آخر جهش خواهد کرد و کاری به قطعات catch ندارد.
اما در اینجا در اولین try عددی بر صفر تقسیم شده است بنابراین کنترل برنامه به بلوک catch منتقل می شود و صرفا نوع خطای رخ داده شده نوشته و نمایش داده می شود. سپس برنامه به کار عادی خودش ادامه می دهد.

تعدادی از کلاس های exception در سی شارپ که از کلاس System.Exception ارث برده اند به شرح زیر هستند :


• Exception Class - - Cause
• SystemException - A failed run-time check;used as a base class for other.
• AccessException - Failure to access a type member, such as a method or field.
• ArgumentException - An argument to a method was invalid.
• ArgumentNullException - A null argument was passed to a method that doesn't accept it.
• ArgumentOutOfRangeException - Argument value is out of range.
• ArithmeticException - Arithmetic over - or underflow has occurred.
• ArrayTypeMismatchException - Attempt to store the wrong type of object in an array.
• BadImageFormatException - Image is in the wrong format.
• CoreException - Base class for exceptions thrown by the runtime.
• DivideByZeroException - An attempt was made to divide by zero.
• FormatException - The format of an argument is wrong.
• IndexOutOfRangeException - An array index is out of bounds.
• InvalidCastExpression - An attempt was made to cast to an invalid class.
• InvalidOperationException - A method was called at an invalid time.
• MissingMemberException - An invalid version of a DLL was accessed.
• NotFiniteNumberException - A number is not valid.
• NotSupportedException - Indicates sthat a method is not implemented by a class.
• NullReferenceException - Attempt to use an unassigned reference.
• OutOfMemoryException - Not enough memory to continue execution.
• StackOverflowException - A stack has overflown.


در کد فوق صرفا عمومی ترین نوع از این کلاس ها که شامل تمامی این موارد می شود مورد استفاده قرار گرفت یعنی :


catch ( Exception e )


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

مثالی دیگر: ( در این مثال خطایابی دقیق تر با استفاده از کلاس های فوق و همچنین مفهوم finally نیز گنجانده شده است )


int a, b = 0 ;
Console.WriteLine( "My program starts" ) ;
try
{
a = 10 / b;
}
catch ( InvalidOperationException e )
{
Console.WriteLine ( e ) ;
}
catch ( DivideByZeroException e)
{
Console.WriteLine ( e ) ;
}
finally
{
Console.WriteLine ( "finally" ) ;
}
Console.WriteLine ( "Remaining program" ) ;
The output here is:
My program starts
System.DivideByZeroException: Attempted to divide by zero.
at ConsoleApplication4.Class1.Main(String[] args) in
d:dont deleteconsoleapplication4class1.cs:line 51
finally
Remaining program


قسمت موجود در قطعه ی فاینالی همواره صرفنظر از قسمت های دیگر اجرا می شود.

به مثال زیر دقت کنید :


int a, b = 0 ;
Console.WriteLine( "My program starts" )
try
{
a = 10 / b;
}
finally
{
Console.WriteLine ( "finally" ) ;
}
Console.WriteLine ( "Remaining program" ) ;
Here the output is
My program starts
Exception occurred: System.DivideByZeroException:
Attempted to divide by zero.at ConsoleApplication4.Class1.
Main(String[] args) in d:dont deleteconsoleapplication4
class1.cs:line 51
finally


قسمت چاپ Remaining program اجرا نشده است.

عبارت throw :

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

مثال :


int a, b = 0 ;
Console.WriteLine( "My program starts" ) ;
try
{
a = 10 / b;
}
catch ( Exception e)
{
throw
}
finally
{
Console.WriteLine ( "finally" ) ;
}


در این حالت قسمت فاینالی اجرا شده و برنامه بلافاصله خاتمه پیدا می کند.

 

سایر مقالات مرتبط با این موضوع

 

 


این مطلب مربوط به موضوع سی شارپ میباشد.

مقدمه ای بر سی شارپ : قسمت هفدهم

(مربوط به موضوع سی شارپ)

مقدمه ای بر سی شارپ : قسمت هفدهم


در کلاس CCommObj که با آن آشنا شدیم ، آرایه ای Private از نوع ICommObjEvents به نام m_arSinkColl وجود دارد. این آرایه تمام اینترفیس های sink شده را ذخیره می کند. واژه ی sink در اینجا به کلاسی گفته می شود که دریافت کننده ی رخدادها است. متد Advise تنها sink وارده به آنرا در یک آرایه ذخیره می کند و سپس اندیس آرایه را که در اینجا cookie نامیده شده است بر می گرداند. این کوکی توسط کلاینتی که دیگر نمی خواهد از آن آیتم هیچونه رخدادی را دریافت کند به سرور فرستاده می شود و سپس سرور این آیتم را از لیست خودش حذف خواهد کرد.

نحوه ی فراخوانی متد advise توسط کلاینت نیز جالب است.


public void Init(CCommObj theSource)
{
m_Server = theSource;
theSource.Advise (this);
string strAdd = ("Hello");
m_Server.read (strAdd,10);
}


در اینجا تنها یک this بعنوان آرگومان به متد advice فرستاده شده است در حالیکه انتظار می رفت آرگومانی از نوع ICommObjEvents به تابع فرستاده شود. دلیل صحت این عمل بدین صورت است که کلاس ClientApp_A از اینترفیس ICommObjEvents ارث برده است و آنرا پیاده سازی نموده است.
در ادامه لیست کامل برنامه ی نوشته شده را در حالت Console ملاحظه می فرمایید.


namespace CSharpCenter
{

using System;

public interface ICommObjEvents
{
void OnDataSent();
void OnError();
}
public class CCommObj
{
private int m_nIndex;
public ICommObjEvents [] m_arSinkColl;
public CCommObj()
{
m_arSinkColl = new ICommObjEvents[10];
m_nIndex = 0;
}

public void Advise(ICommObjEvents theSink)
{

m_arSinkColl[m_nIndex] = theSink;
m_nIndex++;
}
public void SendData(string strData)
{
foreach ( ICommObjEvents theSink in m_arSinkColl)
{
if(theSink != null )
{
theSink.OnDataSent ();
}
}
}
}
class CClientApp_A:ICommObjEvents
{
public void OnDataSent()
{
Console.WriteLine("OnDataSent Client App A");
}
public void OnError()
{
Console.WriteLine("OnError");
}
public void Read()
{
string strAdd = ("Hello");
m_Server.SendData (strAdd);

}
private CCommObj m_Server;
public void Init(CCommObj theSource)
{
m_Server = theSource;
theSource.Advise (this);
}
}
class CClientApp_B:ICommObjEvents
{
public void OnDataSent()
{
Console.WriteLine("OnDataSent Client App B");
}
public void OnError()
{
Console.WriteLine("OnError");
}
private CCommObj m_Server;
public void Init(CCommObj theSource)
{
m_Server = theSource;
theSource.Advise (this);
}
}
class ConsoleApp
{
public static void Main()
{
CClientApp_A theClient = new CClientApp_A ();
CClientApp_B theClient2 = new CClientApp_B ();
CCommObj theComm = new CCommObj ();
theClient.Init (theComm);
theClient2.Init (theComm);
theClient.Read();

}
}

}



در متد Main برنامه ی فوق ، ما دو کلاینت تعریف کرده ایم و یک نمونه از CCommObj را. دو کلاینت instance های CCommObj را بعنوان آرگومان دریافت کرده اند. در هنگام فراخوانی init توسط هر کلاینت متد advise فراخوانی می گردد. در خاتمه Read مربوط به کلاینت 1 فراخوانی شده است که سبب می شود تا رخداد OnDataSend شیء CCommObj اجرا شود و به تمام کلاینت ها فرستاده شود.

هدف از این مثال ارائه ی بعضی از جنبه های اینترفیس ها و نحوه ی استفاده از آنها بود. دو مطلب دیگر در مورد اینترفیس ها باقی مانده اند تا به پایان بحث مربوط به آنها برسیم:

چگونه می توان متوجه شد که یک شیء واقعا یک اینترفیس را پیاده سازی کرده است؟
دو روش برای فهمیدن این موضوع وجود دارد:
- استفاده از کلمه ی کلیدی is
- استفاده از کلمه ی کلیدی as

اولین مثال زیر از کلمه ی کلیدی is استفاده می کند :


CClientApp_C theClient3 = new CClientApp_C ();
if(theClient3 is ICommObjEvents)
Console.WriteLine ("theClient3 implements ICommObjEvents");
else
Console.WriteLine ("theClient3 doesnot implement ICommObjEvents");


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


ICommObjEvents theClient5 = theClient3 as ICommObjEvents;
if(theClient5 != null )
Console.WriteLine ("Yes theClient implements interface");

else
Console.WriteLine ("NO,Yes theClient doesn't implements interface");


در مثال فوق اپراتور as در حال casting شیء theClient5 به ICommObjEvents می باشد. چون CClientApp_C اینترفیس را پیاده سازی نمی کند حاصل خط اول نال خواهد بود.

به صورت خلاصه :
یک اینترفیس قراردادی است که به کلاینت گارانتی می دهد یک کلاس خاص چگونه رفتار خواهد کرد. هنگامیکه کلاسی یک اینترفیس را پیاده سازی می کند به تمام کلاینت ها می گوید که : من تمام موارد ذکر شده در اینترفیس را ارائه و پیاده سازی خواهم کرد. نمونه ی عملی استفاده از اینترفیس ها بحث dot net remoting است.

 

سایر مقالات مرتبط با این موضوع

 


این مطلب مربوط به موضوع سی شارپ میباشد.

مقدمه ای بر سی شارپ : قسمت شانزدهم

(مربوط به موضوع سی شارپ)

مقدمه ای بر سی شارپ : قسمت شانزدهم


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


public abstract class Named
{
public abstract String Name {get; set;} // property
public abstract void PrintName(); // method
}
public class B : Named
{
private String name = "empty";
public override String Name
{
get{return name;}
set{name=value;}
}
public override void PrintName()
{
Console.WriteLine("Name is {0}", name);
}
}


والی که شاید پیش بیاید این است که اگر interface ها صرفا تعریف توابع و خواص را می توانند در خود جای دهند پس چه دلیلی برای بکار بردن آنها و طولانی کردن کار کد نویسی وجود دارد؟
کاربردهای زیادی را می توان برای اینترفیس ها برشمرد. اینترفیس یک رفتار را تعریف می کند. فرض کنید در حال توسعه ی برنامه ایی هستید که بر روی دو کامپیوتر مختلف باید با هم در ارتباط مستقیم بوده و برهم کنش داشته باشند و هر برنامه از ماژولی به نام CCommObj communication object استفاده می نماید. یکی از متدهای این شیء ، SendData() می باشد که رشته ای را دریافت کرده و به برنامه ی دیگر می فرستد. این فراخوانی از نوع asynchronous است زیرا ما نمی خواهیم اگر خطایی در شبکه رخ داد، برنامه برای همیشه منتظر باقی بماند. اما چگونه برنامه ی A که تابع ذکر شده را فراخوانی کرده است می تواند تشخیص دهد که پیغام به مقصد رسیده است یا خیر و یا آیا خطایی در شبکه مانع رسیدن پیغام گشته است یا خیر؟ جواب بدین صورت است که CCommObj هنگام دریافت پیغام ، رخدادی را سبب خواهد شد و اگر خطایی رخ داده باشد خیر. در این حالت نیاز به یک ماژول logging نیز احساس می گردد تا خطاهای رخ داده را ثبت نماید. یک روش انجام آن این است که CCommObj پیاده سازی این امکان را نیز بعهده گرفته و اگر فردا نیز خواستیم ماژول دیگری را به برنامه اضافه کنیم هر روز باید CCommObj را تغییر دهیم. تمام این کارها را به سادگی می توان در یک اینترفیس مدل کرد. روش آن نیز در ادامه بیان می گردد:
در ابتدا یک اینترفیس ایجاد می کنیم تا لیست تمام امکانات ممکن را "منتشر" کند:


interface ICommObjEvents
{
void OnDataSent();
void OnError();
}


شی ء CCommObj ما از این توابع که بعدا توسعه داده خواهند شد برای با خبر سازی کلاینت ها استفاده می نماید. تمام متدها در یک اینترفیس ذاتا پابلیک هستند بنابراین نیازی به ذکر صریح این مطلب نمی باشد و اگر اینکار را انجام دهید کامپایلر خطای زیر را گوشزد خواهد کرد :


The modifier 'public' is not valid for this item


در ادامه کلاینت CClientApp_A را پیاده سازی خواهیم کرد :


class CClientApp_A:ICommObjEvents
{
public void OnDataSent()
{
Console.WriteLine("OnDataSent");
}
public void OnError()
{
Console.WriteLine("OnError");
}
private CCommObj m_Server;
public void Init(CCommObj theSource)
{
m_Server = theSource;
theSource.Advise (this);
string strAdd = ("N450:1");
m_Server.read (strAdd,10);
}
}


در کد فوق کلاس CClientApp_A از ICommObjEvents ارث برده و تمام متدهای این اینترفیس را پیاده سازی نموده است. هنگامی که CCommObj تابع OnDataSent را فراخوانی می کند این کلاینت پیغام را دریافت خواهد کرد. لازم به ذکر است که کلاس کلاینت ما چون از یک اینترفیس ارث بری می نماید پس باید تمام توابع و خواص کلاس پایه را پیاده سازی کند در غیر اینصورت هر چند برنامه کامپایل خواهد شد اما هنگامی که شیء CCommObj هر کدام از توابع این کلاس را فراخوانی کد ، خطای زمان اجرا رخ خواهد داد.
متد Init کلاس فوق آرگومانی را از نوع CCommObj دریافت نموده و در یک متغیر private آنرا ذخیره می نماید. همچنین در این متد ، متد Advise از کلاس CCommObj نیز فراخوانی گشته است.


public class CCommObj
{
private int m_nIndex;
public ICommObjEvents [] m_arSinkColl;
public CCommObj()
{
m_arSinkColl = new ICommObjEvents[10];
m_nIndex = 0;
}
public int Advise(ICommObjEvents theSink)
{
m_arSinkColl[m_nIndex] = theSink;
int lCookie = m_nIndex;
m_nIndex++;
return lCookie
}
public void SendData(string strData)
{
foreach ( ICommObjEvents theSink in m_arSinkColl)
if(theSink != null )
theSink.OnDataSent ();
}
}

 

سایر مقالات مرتبط با این موضوع

 


این مطلب مربوط به موضوع سی شارپ میباشد.
سرزمین دانلود، مرجع دانلود و آموزش نرم افزار

سرزمین دانلود را دنبال کنید !

عضویت در خبرنامه سرزمین دانلود

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



------------------------------------------