مقدمه اي بر سي شارپ : قسمت بيستم
مقدمه اي بر سي شارپ : قسمت بيستم
Delegates
Delegates در سي شارپ روشي مطمئن و typesafe را براي بكار گيري مفهوم function pointer ارائه مي دهند. يكي از ابتدايي ترين استفاده هاي function pointers پياده سازي callback مي باشد. اما در ابتدا لازم است تا با اصول اوليه ي كاري آن آشنا شويم.
مثال يك :
يك delegate چگونه تعريف و استفاده مي شود؟
Delegate يك شيء است كه بيانگر يك تابع مي باشد بنابراين مي تواند بعنوان آرگومان ورودي يك تابع ديگر و يا عضوي از يك كلاس بكار رود.
در زبان "function-pointer" ، Func1() اشاره گري به Func2() را بعنوان پارامتر دريافت كرده و نهايتا آنرا فراخواني مي كند.
در زبان "delegate" ، Func1() يك شيء delegate از Func2() را دريافت كرده و سپس آنرا فراخواني مي كند.
در مثال زير از دو تابع براي شرح اين مطلب سود جسته شده است:
Func1() از delegate استفاده مي كند.
Func2() يك delegate است.
( شماره گذاري خطوط ، در كد زير ، صرفا براي راحت تر شدن توضيحات در مورد آنها است و لزومي به تايپ آنها در برنامه ي اصلي نيست. ) <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
01 using System;
02 delegate void Delg(string sTry);
03 public class Example1{
// function which uses the delegate object
04 private static void Func1(Delg d){
05 d("Passed from Func1");
06 }
// function which is passed as an object
07 private static void Func2(string sToPrint){
08 Console.WriteLine("{0}",sToPrint);
09 }
// Main execution starts here
10 public static void Main(){
11 Delg d = new Delg(Func2);
12 Func1(d);
13 }
14 }
LINE 02
يك شيء delegate را براي Func2 تعريف مي كند.
LINE 04-06
تابعي را تعريف كرده است كه آرگومان ورودي آن از نوع Delg است.
LINE 07-09
تابعي را تعريف مي كند كه بايد به صورت delegate به تابع ديگر فرستاده شود.
LINE 10-14
تابع Main اجراي برنامه را با ايجاد يك شيء delegate براي Func2 آغاز كرده و سپس تابع Func1 را فراخواني مي كند.
مثال 2:
چگونه مي توان از delegates در كارهاي عملي استفاده كرد؟
طرح يك مساله:
شخصي تقاضاي ثبت نام در يك مؤسسه ي آموزشي و همچنين تقاضاي كاريابي در يك شركت را داده است. هر كدام از اين نهادها روشي خاص خود را براي ارزيابي شخص دارند.
راه حل (با روشي شيء گرا):
شخص مشخصاتي همچون سن / جنس / ميزان تحصيلات قبلي / تجربيات كاري و مدارك مرتبط دارد.
مؤسسه ي آموزشي تعدادي از اين مشخصات را براي ارزيابي شخص استفاده مي كند و اين امر در مورد شركت ياد شده نيز صادق است.
شيء شركت و شيء آموزشگاه هر كدام توابع ارزيابي خاص خودشان را پياده سازي مي كنند.
شخص ، اينترفيسي واحدي را در اختيار شركت / آموزشگاه براي ارزيابي خود قرار مي دهد.
پياده سازي (با استفاده از سي شارپ):
ما delegateايي را تعريف مي كنيم كه بيانگر اينترفيسي است كه به شركت و آموزشگاه اجازه ي چك كردن شخص را مي دهد.
سه كلاس school و company و person را تعريف مي نماييم.
كلاس test را براي آزمودن اين موارد ايجاد مي كنيم.
01 using System;
02 using System.Collections;
03 public delegate bool GetChecker(Person p);
// Person has his information with him as he
// applies for School and Company
04 public class Person
05 {
06 public string Name;
07 public int Age;
08 public bool Graduate;
09 public int YearsOfExp;
10 public bool Certified;
11 public Person(string name,
int age,
bool graduate,
int yearsOfExp,
bool certified)
12 {
13 Name=name;
14 Age=age;
15 Graduate=graduate;
16 YearsOfExp=yearsOfExp;
17 Certified=certified;
18 }
19 public bool CheckMe(GetChecker checker)
20 {
21 return(checker(this));
22 }
23 }
// A school, the person applied for higher studies
24 public class School
25 {
26 public static bool SchoolCheck(Person p)
27 {
28 return (p.Age>10 && p.Graduate);
29 }
30 }
// A Company, the person wants to work for
31 public class Company
32 {
33 public static bool CompanyCheck(Person p)
34 {
35 return (p.YearsOfExp>5 && p.Certified);
36 }
37 }
// A Test class, displays delegation in action
38 public class Test
39 {
40 public static void Main()
41 {
42 Person p1 = new Person("Jack",20,true,6,false);
43 Console.WriteLine("{0} School Check : {1}",
p1.Name,
p1.CheckMe(new GetChecker(School.SchoolCheck)));
44 Console.WriteLine("{0} Company Check : {1}",
p1.Name,
p1.CheckMe(new GetChecker(Company.CompanyCheck)));
45 }
46 }
LINE 03
Delegate مورد نياز را تعريف مي كند.
LINE 04-23
كلاس person را تعريف مي كند. اين كلاس تابعي پابليك را ارائه مي دهد كه آرگومان ورودي آن از نوع GetChecker مي باشد.
LINE 24-30
كلاس school را تعريف مي كند و سپس تابعي را كه delegate است ارائه مي دهد.
LINE 31-37
كلاس company را تعريف مي كند و سپس تابعي را كه delegate است ارائه مي دهد.
LINE 38-36
كلاس test را پياده سازي مي نمايد. سپس يك شيء شخص ساخته مي شود. در ادامه new GetChecker(School.SchoolCheck) و newGetChecker(Company.CompanyCheck) شيء ايي را ايجاد مي كند از نوع delegate مورد نياز و آنرا به تابع CheckMe مي فرستد. خروجي نتيجه ي ارزيابي اين شخص مي باشد.
اگر چك كردن اشخاص بيشتري نياز باشد به اين صورت عمل مي شود:
Person p1 = new Person("Jack",20,true,6,false);
Person p2 = new Person("Daniel",25,true,10,true);
GetChecker checker1= new GetChecker(School.SchoolCheck);
GetChecker checker2= new GetChecker(School.CompanyCheck);
Console.WriteLine("{0} School Check : {1}",
p1.Name,p1.CheckMe(checker1));
Console.WriteLine("{0} Company Check : {1}",
p1.Name,p1.CheckMe(checker2));
Console.WriteLine("{0} School Check : {1}",
p2.Name,p2.CheckMe(checker1));
Console.WriteLine("{0} Company Check : {1}",
p2.Name,p2.CheckMe(checker2));
مثال 3 :
Delegates در تعامل بين دات نت فريم ورك و سي شارپ چه نقشي دارد؟
طرح يك مساله:
نمايش دادن ميزان پيشرفت خواندن يك فايل هنگامي كه حجم فايل بسيار زياد است.
راه حل ( با استفاده از سي شارپ):
در مثال زير از كلاس FileReader براي خواندن يك فايل حجيم استفاده شده است. هنگاميكه برنامه مشغول خواندن فايل است 'Still reading.. را نمايش مي دهد و در پايان 'Finishedreading..'. را عرضه مي كند.
براي اينكار از فضاي نام System.IO استفاده شده است. اين فضاي نام حاوي delegate ايي مهيا شده براي ما مي باشد. بدين ترتيب مي توانيم به دات نت فريم ورك بگوييم كه ما تابعي را تعريف كرده ايم كه او مي تواند آنرا فراخواني كند.
سؤال: چه نيازي وجود دارد تا دات نت فريم ورك تابع ما را فراخواني و اجرا كند؟ با استفاده از تابع ما كه دات نت فريم آنرا صدا خواهد زد در طول خواندن فايل به ما گفته مي شود كه بله! من هنوز مشغول خواندن هستم! به اين عمليات Callback نيز گفته مي شود. به اينكار پردازش asynchronous نيز مي گويند!
01 using System;
02 using System.IO;
03 public class FileReader{
04 private Stream sInput;
05 private byte[ ] arrByte;
06 private AsyncCallback callbackOnFinish;
07 public FileReader(){
08 arrByte=new byte[256];
09 callbackOnFinish = new AsyncCallback(this.readFinished);
10 }
11 public void readFinished(IAsyncResult result){
12 if(sInput.EndRead(result)>0){
13 sInput.BeginRead(arrByte,
0,
arrByte.Length,
callbackOnFinish,
null);
14 Console.WriteLine("Still reading..");
15 }
16 else Console.WriteLine("Finished reading..");
17 }
18 public void readFile(){
19 sInput = File.OpenRead(@"C:\big.dat");
20 sInput.BeginRead(arrByte,
0,
arrByte.Length,
callbackOnFinish,
null);
21 for(long i=0;i<=1000000000;i++){
// just to introduce some delay
22 }
23 }
24 public static void Main(){
25 FileReader asynctest=new FileReader();
26 asynctest.readFile();
27 }
28 }
LINE 02
فضاي نام System.IO را به برنامه ملحق مي كند. اين فضاي نام به صورت خودكار حاوي تعريف delegate زير مي باشد:
public delegate void AsyncCallback (IAsyncResult ar);
LINE 03-10
تعريف كلاس
LINE 06
شيء delegate را تعريف مي كند.
LINE 07-10
سازنده ي كلاس را پياده سازي مي كنند. در اينجا ما تصميم گرفته ايم كه بافري حاوي 256 بايت را در هر لحظه بخوانيم.
LINE 09
شيء delegate نمونه سازي شده است.
LINE 18-23
readFile را پياده سازي مي كند.
LINE 12-16
نحوه ي استفاده از شيء IAsyncResult را بيان مي كند.
LINE 12
sInput.EndRead(result) تعداد بايتهاي خوانده شده را بر مي گرداند. اين خواندن تاجايي كه تعداد بايتهاي خوانده شده صفر است ادامه پيدا مي كند و در اينجا 'Finished reading..' اعلام مي گردد.
منبع:
مطالب مشابه :
آموزش برنامه نویسی گرافیک در سی شارپ_قسمت نهم
دستورات گرافیک سی شارپ #c آموزش برنامه نویسی گرافیک سی شارپ ساخت کامپوننت در سی شارپ
عضویت در بخش:آموزش برنامه نویسی سی شارپ c# windows Application
دستورات گرافیک سی شارپ #c آموزش برنامه نویسی گرافیک سی شارپ ساخت کامپوننت در سی شارپ
آموزش برنامه نویسی گرافیک در سی شارپ_قسمت یازدهم
C# windows Application آموزش برنامه نویسی سی شارپ: ايجاد يك پروژه تحت ويندوز در دات نت. بررسي فرم ها در
گرافیک در سی شارپ
گرافیک در سی شارپ. پروژه درس گرافیک برچسبها: graphic, C, گرافیک, سی شارپ, Source Code
مقدمه اي بر سي شارپ : قسمت سوم
دستورات گرافیک سی شارپ #c آموزش برنامه نویسی گرافیک سی شارپ ساخت کامپوننت در سی شارپ
مقدمه اي بر سي شارپ : قسمت بيستم
آموزش گرافیک در سی شارپ. مقدمه اي بر سي شارپ : قسمت بيستم . مقدمه اي بر سي شارپ : قسمت بيستم .
گرافیک در سی شارپ(استاد دوره : مهندس وحید اشرف)
الگوریتم رسم خط در سی شارپ: ابتدا یک عکس یا جعبه عکس در فرم قرار می دهیم: public partial class Form1: Form
آموزش برنامه نویسی سی شارپ C# windows Application - قسمت ششم
دستورات گرافیک سی شارپ #c آموزش برنامه نویسی گرافیک سی شارپ ساخت کامپوننت در سی شارپ
مقدمه اي بر سي شارپ : قسمت هفتم
دستورات گرافیک سی شارپ #c آموزش برنامه نویسی گرافیک سی شارپ ساخت کامپوننت در سی شارپ
آشنایی با کلاسها و اشیا (3)
رسم و گرافیک در سی شارپ [این مطلب در خصوص وراثت آمده و در بخش های بعدی مطلب گرافیک بصورت مجزا
برچسب :
گرافیک در سی شارپ