Make your own free website on Tripod.com

دروس مرتبط

 

  صفحه اصلی > آموزش #C > رخدادها و Delegate ( اول)

   

> معرفی #C

     آغاز کار با #C

     متغیرها،عبارات وعملگرها

     دستورهای کنترلی شرطی

     دستورهای کنترلی حلقه ای

 

> قالب برنامه ها

     کلاسها در #C

     آشنایی با NameSpace

     چگونگی نوشتن متد

     ساختارها (Structure)

 

> کار با کامپوننت ها

     ویژگی ها (Properties)

     صفات (Attribute)( اول)

     صفات (Attribute)( دوم)

     رخدادها و Delegate

     ( اول)

    رخدادها و Delegate

    ( دوم)

    رخدادها و Delegate

    ( سوم)

    کنترل خطاها

 

 
 

 رخدادها و delegate ها در  C#(بخش اول)

نكته مهم قبل از مطالعه اين درس

توجه نماييد، delegate ها و رخدادها بسيار با يكديگر در تعامل‌اند، از اينرو در برخي موارد، قبل از آموزش و بررسي رخدادها، به ناچار، از آنها نيز استفاده شده و يا به آنها رجوع شده است. رخدادها در قسمت انتهايي اين درس مورد بررسي قرار مي‌گيرند، از اينرو در صورتيكه در برخي موارد دچار مشكل شديد و يا درك مطلب برايتان دشوار بود، ابتدا كل درس را تا انتها مطالعه نماييد و سپس در بار دوم با ديدي جديد به مطالب و مفاهيم موجود در آن نگاه كنيد. در اغلب كتابهاي آموزشي زبان C# نيز ايندو مفهوم با يكديگر آورده شده‌اند ولي درك رخدادها مستلزم درك و فراگيري كامل delegate هاست، از اينرو مطالب مربوط به delegate ها را در ابتدا قرار داده‌ام.

هدف ما در اين درس به شرح زير است :

     مقدمه

     درك اينكه يك delegate چيست؟

     اعلان و پياده‌سازي delegate ها

    

طي درسهاي گذشته، چگونگي ايجاد و پيادسازي انواع مرجعي (Reference Type) را با استفاده از ساختارهاي زبان C#، يعني كلاسها (Class) و واسطها (Interface)، فرا گرفتيد. همچنين فرا گرفتيد كه با استفاده از اين انواع مرجعي، ميتوانيد نمونه‌هاي جديدي از اشياء را ايجاد كرده و نيازهاي توسعه نرم‌افزار خود را تامين نماييد. همانطور كه تا كنون ديديد، با استفاده از كلاسها قادر به ساخت اشيائي هستيد كه داراي صفات (Attribute) و رفتارهاي (Behavior) خاصي بودند. با استفاده از واسطها، يكسري از صفات و رفتارها را تعريف مي‌كرديم تا فرم كلي داشته باشيم و تمام اشياء خود به پياده‌سازي اين صفا و رفتارها مي‌پرداختند. در اين درس با يكي ديگر از انواع مرجعي (Reference Type) در زبان C# آشنا خواهيد شد.

مقدمه‌اي بر رخداد‌ها و delegate ها

در گذشته، پس از اجراي يك برنامه، برنامه مراحل اجراي خود را مرحله به مرحله اجرا مي‌نمود تا به پايان برسد. در صورتيكه نياز به ارتباط و تراكنش با كاربر نيز وجود داشت، اين امر محدود و بسيار كنترل شده صورت مي‌گرفت و معمولاً ارتباط كاربر با برنامه تنها پر كردن و يا وارد كردن اطلاعات خاصي در فيلدهايي مشخص بود.

امروزه با پبشرفت كامپيوتر و گسترش تكنولوژيهاي برنامه نويسي و با ظهور رابطهاي كاربر گرافيكي (GUI) ارتباط بين كاربر و برنامه بسيار گسترش يافته و ديگر اين ارتباط محدود به پر كردن يكسري فيلد نيست، بلكه انواع عمليات از سوي كاربر قابل انجام است. انتخاب گزينه‌اي خاص در يك منو، كليك كردن بر روي دكمه‌ها براي انجام عملياتي خاص و ... . رهيافتي كه امروزه در برنامه‌نويسي مورد استفاده است، تحت عنوان "برنامه‌نويسي بر پايه رخدادها" (Event-Based Programming) شناخته مي‌شود. در اين رهيافت برنامه همواره منتظر انجام عملي از سوي كاربر مي‌ماند و پس از انجام عملي خاص، رخداد مربوط به آن را اجرا مي‌نمايد. هر عمل كاربر باعث اجراي رخدادي مي‌شود. در اين ميان برخي از رخدادها بدون انجام عملي خاص از سوي كاربر اجرا مي‌شوند، همانند رخدادهاي مربوط به ساعت سيستم كه مرتباً در حال اجرا هستند.

رخدادها (Events) بيان اين مفهوم هستند كه در صورت اتفاق افتادن عملي در برنامه، كاري بايد صورت گيرد. در زبان C# مفاهيم Event و Delegate دو مفهوم بسيار وابسته به يكديگر هستند و با يكديگر در تعامل مي‌باشند. براي مثال، مواجهه با رخدادها و انجام عمل مورد نظر در هنگام اتفاق افتادن يك رخداد، نياز به يك event handler دارد تا در زمان بروز رخداد، بتوان به آن مراجعه نمود. Event handler ها در C# معمولاً با delegate ها ساخته مي‌شوند.

از delegate ، مي‌توان به عنوان يك Callback ياد نمود، بدين معنا كه يك كلاس مي‌تواند به كلاسي ديگر بگويد : "اين عمل خاص را انجام بده و هنگاميكه عمليات را انجام دادي منرا نيز مطلع كن". با استفاده از delegate ها، همچنين مي‌توان متدهايي تعريف نمود كه تنها در زمان اجرا قابل دسترسي باشند.

 ابتدای صفحهF

Delegate

Delegate ها، يكي ديگر از انواع مرجعي زبان C# هستند كه با استفاده از آنها مي‌توانيد مرجعي به يك متد داشته باشيد، بدين معنا كه delegate ها، آدرس متدي خاص را در خود نگه ميدارند. در صورتيكه قبلاً با زبان C برنامه‌نويسي كرده‌ايد، حتماً با اين مفهوم آشنايي داريد. در زبان C اين مفهوم با اشاره‌گرها (pointer) بيان مي‌شود. اما براي افرادي كه با زبانهاي ديگري برنامه‌نويسي مي‌كرده‌اند و با اين مفهوم مانوس نيستند، شايد اين سوال مطرح شود كه چه نيازي به داشتن آدرس يك متد وجود دارد. براي پاسخ به اين سوال اندكي بايد تامل نماييد.

بطور كلي مي‌توان گفت كه delegate نوعي است شبيه به متد و همانند آن نيز رفتار مي‌كند. در حقيقت delegate انتزاعي (Abstraction) از يك متد است. در برنامه‌نويسي ممكن است به شرايطي برخورد كرده باشيد كه در آنها مي‌خواهيد عمل خاصي را انجام دهيد اما دقيقاً نمي‌دانيد كه بايد چه متد يا شي‌ءاي را براي انجام آن عمل خاص مورد استفاده قرار دهيد. در برنامه‌هاي تحت ويندوز اين گونه مسائل مشهودتر هستند. براي مثال تصور كنيد در برنامه‌ شما، دكمه‌اي قرار دارد كه پس از فشار دادن اين دكمه توسط كاربر شيءاي يا متدي بايد فراخواني شود تا عمل مورد نظر شما بر روي آن انجام گيرد. مي‌توان بجاي اتصال اين دكمه به شيء يا متد خاص، آنرا به يك delegate مرتبط نمود و سپس آن delegate را به متد يا شيء خاصي در هنگام اجراي برنامه متصل نمود.

ابتدا، به نحوه استفاده از متدها توجه نماييد. معمولاً، براي حل مسايل خود الگوريتم‌هايي طراحي مي‌نائيم كه اين الگوريتمهاي كارهاي خاصي را با استفاده از متدها انجام مي‌دهد، ابتدا متغيرهايي مقدار دهي شده و سپس متدي جهت پردازش آنها فراخواني مي‌گردد. حال در نظر بگيريد كه به الگوريتمي نياز داريد كه بسيار قابل انعطاف و قابل استفاده مجدد (reusable) باشد و همچنين در شرايط مختلف قابليت‌هاي مورد نظر را در اختيار شما قرار دهد. تصور كنيد، به الگوريتمي نياز داريد كه از نوعي از ساختمان داده پشتيباني كند و همچنين مي‌خواهيد اين ساختمان داده را در مواردي مرتب (sort) نماييد، بعلاوه ميخواهيد تا اين ساختمان داده از انواع مختلفي تشكيل شده باشد. اگر انواع موجود در اين ساختمان داده را ندانيد، چكونه مي‌خواهيد الگوريتمي جهت مقايسه عناصر آن طراحي كنيد؟‌ شايد از يك حلقه if/then/else و يا دستور switch براي اين منظور استفاده كنيد، اما استفاده از چنين الگوريتمي محدوديتي براي ما ايجاد خواهد كرد. روش ديگر، استفاده از يك واسط است كه داراي متدي عمومي باشد تا الگوريتم شما بتواند آنرا فراخواني نمايد، اين روش نيز مناسب است، اما چون مبحث ما در اين درس delegate ها هستند، مي‌خواهيم مسئله را از ديدگاه delegate ها مورد بررسي قرار دهيم. روش حل مسئله با استفاده از آنها اندكي متفاوت است.

روش ديگر حل مسئله آنست كه،‌ مي‌توان delegate ي را به الگوريتم مورد نظر ارسال نمود و اجازه داد تا متد موجود در آن،‌عمل مورد نظر ما را انجام دهد. چنين عملي در مثال 1-14 نشان داده شده است.

(به صورت مسئله توجه نماييد : ميخواهيم مجموعه‌اي از اشياء را كه در يك ساختمان داده قرار گرفته‌اند را مرتب نمائيم. براي اينكار نياز به مقايسه اين اشياء با يكديگر داريم. از آنجائيكه اين اشياء از انواع (type) مختلف هستند به الگوريتمي نياز داريم تا بتواند مقايسه بين اشياء نظير را انجام دهد. با استفاده از روشهاي معمول اين كار امكان پذير نيست، چراكه نمي‌توان اشيائئ از انواع مختلف را با يكديگر مقايسه كرد. براي مثال شما نمي‌توانيد نوع عددي int را با نوع رشته‌اي string مقايسه نماييد. به همين دليل با استفاده از delegate ها به حل مسئله پرداخته‌ايم. به مثال زير به دقت توجه نماييد تا بتوانيد به درستي مفهوم delegate را درك كنيد.)

ابتدای صفحهF

مثال 1-14 : اعلان و پياده‌سازي يك delegate

using System;

// در اينجا اعلان مي‌گردد. delegate

public delegate int Comparer(object obj1, object obj2);

public class Name

{

public string FirstName = null;

public string LastName = null;

public Name(string first, string last)

{

FirstName = first;

LastName = last;

}

// delegate method handler

public static int CompareFirstNames(object name1, object name2)

{

string n1 = ((Name)name1).FirstName;

string n2 = ((Name)name2).LastName;

if (String.Compare(n1, n2) > 0)

{

return 1;

}

else if (String.Compare(n1, n2) < 0)

{

return -1;

}

else

{

return 0;

}

}

public override string ToString()

{

return FirstName + " " + LastName;

}

}

 

class SimpleDelegate

{

Name[] names = new Name[5];

public SimpleDelegate()

{

names[0] = new Name("Meysam", "Ghazvini");

names[1] = new Name("C#", "Persian");

names[2] = new Name("Csharp", "Persian");

names[3] = new Name("Xname", "Xfamily");

names[4] = new Name("Yname", "Yfamily");

}

static void Main(string[] args)

{

SimpleDelegate sd = new SimpleDelegate();

// delegate ساخت نمونه‌اي جديد از

Comparer cmp = new Comparer(Name.CompareFirstNames);

Console.WriteLine("\nBefore Sort: \n");

sd.PrintNames();

 

sd.Sort(cmp);

Console.WriteLine("\nAfter Sort: \n");

sd.PrintNames();

}

 

public void Sort(Comparer compare)

{

object temp;

for (int i=0; i < names.Length; i++)

{

for (int j=i; j < names.Length; j++)

{

//همانند يك متد استفاده مي‌شود compare از

if ( compare(names[i], names[j]) > 0 )

{

temp = names[i];

names[i] = names[j];

names[j] = (Name)temp;

}

}

}

}

public void PrintNames()

{

Console.WriteLine("Names: \n");

foreach (Name name in names)

{

Console.WriteLine(name.ToString());

}

}

}

اولين اعلان در اين برنامه، اعلان delegate است. اعلان delegate بسيا رشبيه به اعلان متد است، با اين تفاوت كه داراي كلمه كليدي delegate در اعلان است و در انتهاي اعلان آن ";" قرار مي‌گيرد و نيز پياده‌سازي ندارد. در زير اعلان delegate كه در مثال 1-14 آورده شده را مشاهده مي‌نماييد :

public delegate int Comparer(object obj1, object obj2);

اين اعلان، مدل متدي را كه delegate مي‌تواند به آن اشاره كند را تعريف مي‌نمايد. متدي كه مي‌توان از آن بعنوان delegate handler براي Comparer استفاده نمود، هر متدي مي‌تواند باشد اما حتماً بايد پارامتر اول و دوم آن از نوع object بوده و مقداري از نوع int بازگرداند. در زير متدي كه بعنوان delegate handler در مثال 1-14 مورد استفاده قرار گرفته است، نشان داده شده است :

public static int ComparerFirstNames(object name1, object name2)

{

 

}

براي استفاده از delegate مي‌بايست نمونه‌اي از آن ايجاد كنيد. ايجاد نمونه جديد از delegate همانند ايجاد نمونه‌اي جديد از يك كلاس است كه به همراه پارامتري جهت تعيين متد delegate handler ايجاد مي‌شود :

Comparer cmp = new Comparer(Name.ComparerFirstName);

در مثال 1-14، cmp بعنوان پارامتري براي متد Sort() مورد استفاده قرار گرفته است.به روش ارسال delegate به متدSort() توجه نماييد :

sd.Sort(cmp);

با استفاده از اين تكنيك، هر متد delegate handler به سادگي در زمان اجرا به متد Sort() قابل ارسال است. براي مثال مي‌توان handler ديگري با نام CompareLastNames() تعريف كنيد، نمونه جديدي از ‍Comparer را با اين پارامتر ايجاد كرده و سپس آنرا به متد Sort() ارسال نماييد.

ابتدای صفحهF  

Back Next

  صفحه اصلی
    C# آموزش
    مفاهیم شی گرایی
    برنامه های نمونه
    کار با محیط
    معرفی کتاب
    نقشه سایت
    درباره ما
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
                               
[صفحه اصلی] [آموزش #C] [مفاهیم شی گرایی] [برنامه های نمونه] [کار با محیط] [معرفی کتاب] [نقشه سایت] [درباره ما]