آموزش سی شارپ c# درس پنجم

 
ارسال شده در تاریخ 1392/7/22 توسط admin در زمینه آموزش سی شارپ
 
درس پنجم - متدها
 
در این قسمت با متدها در زبان C# آشنا می شوید . اهداف این درس به شرح زیر می باشد : درک ساختار یک متد
درک تفاوت بین متدهای استاتیک (static methods) و متدهای نمونه (instance) ایجاد نمونه جدید از اشیاء نحوه فراخوانی متدها
درک چهار گونه متفاوت پارامترها نحوه استفاده از مرجع this
 
تا کنون تمامی اعمالی که ما در برنام ه هایمان انجام می دادیم در متد Main() اتفاق می افتادند . این روش برای برنامه های ساده و ابتدایی که استفاده کردیم مناسب بود، اما اگر برنام ه ها پیچید هتر شوند و تعداد کارهای مورد نظر ما گسترش یابد، استفاده از متدها
جایگزین روش قبل می گردد . متدها فوق العاده مفید هستند، چراکه کارها را به بخشهای کوچکتر و مجزا تقیسم می کنند و در نتیجه استفاده از آنها آسا نتر خواهد بود . ساختار کلی یک متد به صورت زیر است :
[attributes][ modifiers] return-type method-name ([ parameters] ) { statements }
 
دو قسمت attributes و modifiers را در آینده مورد بررسی قرار خواهیم داد return-type . نوعی است یک متد باز می گرداند و میتواند هر یک از انواع تعریف شده زبان C# و یا از انواع تعریف شده توسط کاربر باشد . هر متد با نام آن شناخت ه می شود .
method-name نام انتخابی برنامه نویس برای یک متد است و از طریق همین نام فراخوانی متد انجام می شود . پارامترها (parameters) مول فه ها یا متغیرهایی هستند که برای انجام یکسری پردازش به متد ارسال می شوند و از طریق آنها می توان اطلاعاتی را به متد ارسال و یا از آن دریافت نمود، و در نهایت دستورالعمهای متد، دستورهایی از زبان C# هستند که بوسیله آنها عمل مورد نظر برنام ه نویس انجام می شود و عملی است که یک متد آنرا انجام می دهد . مثال 5-1 پیاده سازی یک متد ساده را نمایش میدهد .
using System;
 
class OneMethod
{
public static void Main()
{
string myChoice;
OneMethod om = new OneMethod(); do
{
myChoice = om.getChoice();
تصمیمی بر اساس انتخاب کاربر گرفته میشود //
switch(myChoice)
{
case "A": case "a":
 
www.IrAnPRoje.com
Console.WriteLine("You wish to add an address."); break; case "D": case "d":
Console.WriteLine("You wish to delete an address."); break; case "M": case "m":
Console.WriteLine("You wish to modify an address."); break; case "V": case "v":
Console.WriteLine("You wish to view the address list."); break; case "Q": case "q":
Console.WriteLine("Bye."); break; default:
Console.WriteLine("{0} is not a valid choice", myChoice); break;
}
اجرای برنامه برای دیدن نتایج موقف میشود //
Console.WriteLine();
Console.Write("Press Enter key to continue..."); Console.ReadLine(); Console.WriteLine();
} while (myChoice != "Q" && myChoice != "q");
اجرای برنامه تا زمانیکه کاربر بخواهد ادامه می یابد //
}
string getChoice()
{
string myChoice;
منویی را نمایش می دهد //
Console.WriteLine("My Address Book "); Console.WriteLine("A - Add New Address"); Console.WriteLine("D - Delete Address"); Console.WriteLine("M - Modify Address"); Console.WriteLine("V - View Addresses"); Console.WriteLine("Q - Quit ");
Console.Write("Choice (A,D,M,V,or Q): ");
ورودی دریافتی از کاربر را بررسی می کند //
myChoice = Console.ReadLine(); Console.WriteLine(); return myChoice;
}
}
 
www.IrAnPRoje.com
 
برنامه مثال 5-1 دقیقا همان برنامه در س 4 است، با این تفاوت که در درس چهارم چاپ منو و دریافت ورودی از کاربر در متد Main() صورت میگرفت در حالیکه در این مثال ، این اعمال در یک متد مجزا بنام getChoice() صورت میگیرد . نوع بازگشتی این متد از نوع رشت ه ای است . از این رشته در دستور switch در متد Main() استفاده میشود . همانطور که ملاحظه می نمایید، پرانتزهای متد getChoice() خالی هستند، یعنی این متد دارای پارامتر نیست، از اینرو هیچ اطلاعاتی ب ه / از این متد منتقل نمی شود .
 
درون این متد، ابتدا متغیر myChoice را اعلان نموده ایم . هرچند نام و نوع این متغیر همانند متغیر myChoice موجود در متد Main() است، اما این دو متغیر دو متغیر کاملاً مجزا از یکدیگر می باشند . هر دو این متغیرها، متغیرهای محلی (Local) هستند، از اینرو تنها درون بلوکی که تعریف شد هاند قابل دسترس می باشند . به بیان دیگر این دو متغیر از وجود یکدیگر اطلاعی ندارند .
 
متد getChoice() منویی را در کنسول نمایش می دهد و ورودی انتخابی کاربر را دریافت می نماید . دستور return دا ده ها را از طریق متغیر myChoice به متد فراخواننده آن، یعنی Main() ، باز می گرداند . توجه داشته باشید که، نوع متغیری که توسط دستور return باز گردانده میشود، باید دقیقاً همانند نوع بازگشتی متد باشد . در این مثال نوع بازگشتی، رشته است .
 
در C# دو گونه متد وجود دارد . یکی متدهای استاتیک (Static) و دیگری متدهای نمونه .(Instance) متدهایی که در اعلان خود شامل کلمه کلیدی static هستند، از نوع استاتیک هستند، بدین معنا که هیچ نمونهای از روی این متد قابل ایجاد نیست و
این تنها همین نمونه موجود قابل استفاده است . از روی متدهای استاتیک نمی توان شیء (Object) ایجاد کرد . در صورتیکه در اعلان متد از کلمه کلیدی static استفاده نشده باشد، متد بعنوان متد نمونه در نظر گرفته می شود، بدین معنا که از روی آن میتوان نمونه ایجاد کرد و شیء تولید نمود . هر یک از اشیاء ایجاد شده از روی این متدها، تمامی عناصر آن متد را دارای میباشند .
 
در این مثال، چون getChoice() بصورت استاتیک اعلان نشده است، پس باید برای استفاده از آن شیء جدیدی تولید شود . تولید شیء جدید بوسیله OneMethod om = new OneMethod() صورت می پذیرد . در سمت چپ این اعلان، مرجع این شیء جدید، یعنی om ، قرار دارد که از نوع OneMethod است . در اینجا توجه به یک نکته بسیار مهم است، om به خودی خود
شیء نیست، بلکه می تواند مرجعی به شی ای از نوع OneMethod() را در خود ن گه دارد . در سمت راست این اعلان، تخصیص شیء جدیدی از نوع OneMethod() به متغیر om صورت گرفته است . کلمه کلیدی new عملگری است که شیء جدیدی را در heap ایجاد می نماید . اتفاقی که اینجا روی داده اینست که نمونه جدیدی از OneMethod() در heap تولید شده و سپس
به مرجع om تخصیص داده می شود . حال که نمونه ای از متد OneMethod() را به om تخصیص دا ده ایم، از طریق om می توانیم با این متد کار نماییم .
 
متدها، فیلدها و سایر اعضای یک کلاس از طریق عملگر نقطه "." قابل دسترس هستند . هنگامیکه می خواهیم متد getChoice() را فراخوانی کنیم، بوسیله عملگر نقطه از طریق om به آن دسترسی پیدا می نماییم . om.getChoice() : برای نگهداری مقداری که getChoice() بر می گرداند، از عملگر "=" استفاده نموده ایم . رشته بازگشتی از متد getChoice() درون متغیر محلی myChoice متد Main() قرار می گیرد . از این قسمت، اجرای برنامه همانند قبل است .
 
پارامترهای متد به مثال 5-2 توجه کنید .
using System;
 
 
 
class Address
{
public string name; public string address;
پایان کلاس }//Address
class MethodParams
{
public static void Main()
{
string myChoice;
MethodParams mp = new MethodParams(); do
{
منویی نمایش داده شده و ورودی از کاربر دریافت میگردد //
myChoice = mp.getChoice();
تصمیمی بر اساس ورودی کاربر گرفته می شود //
mp.makeDecision(myChoice);
جهت دیدن نتایج توسط کاربر، اجرای برنامه موقتا موقف می گردد //
Console.Write("Press Enter key to continue..."); Console.ReadLine(); Console.WriteLine();
} while (myChoice != "Q" && myChoice != "q");
اجرای حلقه تا زمانیکه کاربر بخواهد ادامه پیدا می نماید // پایان متد }//Main
نمایش منو و دریافت ورودی از کاربر //
string getChoice()
{
string myChoice;
نمایش منو //
Console.WriteLine("My Address Book "); Console.WriteLine("A - Add New Address"); Console.WriteLine("D - Delete Address"); Console.WriteLine("M - Modify Address"); Console.WriteLine("V - View Addresses"); Console.WriteLine("Q - Quit ");
Console.WriteLine("Choice (A,D,M,V,or Q): ");
دریافت ورودی کاربر //
myChoice = Console.ReadLine(); return myChoice;
پایان متد }//getChoice() تصم یمگیری //
void makeDecision(string myChoice)
{
Address addr = new Address();
 
 switch(myChoice)
{
case "A": case "a":
addr.name = "Meysam"; addr.address = "C# Persian"; this.addAddress(ref addr); break; case "D": case "d":
addr.name = "Ghazvini"; this.deleteAddress(addr.name); break; case "M": case "m":
addr.name = "CSharp"; this.modifyAddress(out addr);
Console.WriteLine("Name is now {0}.", addr.name); break; case "V": case "v":
this.viewAddresses("Meysam", "Ghazvini", "C#", "Persian"); break; case "Q": case "q":
Console.WriteLine("Bye."); break; default:
Console.WriteLine("{0} is not a valid choice", myChoice); break;
}
}
وارد کردن یک آدرس //
void addAddress(ref Address addr)
{
Console.WriteLine("Name: {0}, Address: {1} added.", addr.name, addr.address);
}
حذف یک آدرس //
void deleteAddress(string name)
{
Console.WriteLine("You wish to delete {0}"s address.", name);
}
تغییر یک آدرس //
void modifyAddress(out Address addr)
{
خطا رخ می دهد //Console.WriteLine("Name: {0}.", addr.name); //
 
 addr = new Address(); addr.name = "Meysam"; addr.address = "C# Persian";
}
نمایش آدرس ها //
void viewAddresses(params string[] names)
{
foreach (string name in names)
{
Console.WriteLine("Name: {0}", name);
}
}
}
 
مثال 5-2 ، نمونه تغییر یافته مثال 5-1 است که در آن تمامی برنامه ماژولار شده و به متدهای مختلف تقسیم شده است . در زبان C# چهار گونه پارامتر وجود دارند ref : ، out ، params و . value بمنظور آشنایی با پارامترها، در مثال 5-2 کلاسی با نام Address با دو فیلد از نوع رشته تولید کردهایم .
 www.IrAnPRoje.com
درون متد Main() ، متد getChoice() را فراخوانی کرده ایم تا از کاربر ور ودی دریافت کنیم و این ورودی در متغیر رشت ه ای myChoice قرار می گیرد . سپس متغیر myChoice را بعنوان آرگومان به متد makeDecision() ارسال نموده ایم . در اعلان myDecision()، همانطور که ملاحظه می نمایید، پارامتر این متد از نوع رشته و با نام myChoice تعریف شده است . توجه نمایید که این متغیر نیز محلی است و تنها درون متد makeDecision() قابل استفاده است . هرگاه در اعلان متد، برای پارامترهای آن هیچ modifier آورده نشود، این پارامتر بعنوان value در نظر گرفته می شود . در مورد پارامترهای مقداری (value parameter) ، اصل مقدار متغیر یا پارامتر به پشته (Stack) کپی می شود . متغیرهایی که بصورت مقداری بعنوان
پارامتر برای یک متد ارسال می شوند، همگی محلی بوده و تغییرات ایجاد شده بر روی آنها به هیچ وجه تغییری بر روی متغیر اصلی ایجاد نمی نماید .
 
دستور switch در متد makeDecision() برای هر case یک متد را فراخوانی می نماید . فراخوانی این متدها با آنچه در متد Main() دید مقداری متفاوت است . علاوه بر مرجع mp ، در این فراخوا نیها از کلمه کلیدی this نیز استفاده شده است . کلمه کلیدی this ارجاعی به شیء فعلی دارد .
 www.IrAnPRoje.com
متد addAddress() پارامتری از نوع ref دارد . وجود چنین پارامتری بدین معناست که مرجعی از این پارامتر به متد ارسال می شود و این مرجع همچنان به شیء اصلی درون heap نیز اشاره دارد چراکه آدرس شیء مورد نظر به متد کپی میشود . در مورد پارامترهای ref ، هرگونه تغییری که بر روی متغیر محلی رخ دهد، همان تغییر بر روی متغیر اصلی نیز اعمال می گردد . امکان تغییر
مرجع وجود ندارد و تنها شی ای که مورد آدرس دهی واقع شده، می تواند تغییر پیدا نماید . پارامترهای مرجعی (ref) را می توان به عنوان عناصر ورودی / خروجی برای متد در نظر گرفت .
 
پارامترهای out در مواردی استفاده می شوند که ارسال اطلاعات به متد از طریق پارامتر مد نظر نباشد، بلکه ارسال اطلاعات از متد مورد نظر باش د . استفاده از این پارامترها از اینرو کارآمد هستند که برنامه مجبور به کپی کردن پارامتر به متد نیست و از حجم
 
www.IrAnPRoje.com
سرباره (Overhead) برنامه می کاهد . در برنامه های عادی این مسئله چندان به چشم نمی آید، اما در برنامه های تحت شبکه که سرعت ارتباط و انتقال داده ها بسیار مهم است، این پارامترها ضروری می شوند .
 
متد modifyAddress() دارای پارامتری از نوع out است . پارامترهای out فقط به متد فراخواننده آن بازگشت داده می شوند . از آنجائیکه این پارامترها از متد فراخواننده هیچ مقداری دریافت نمی کنند و فقط درون متدی که به عنوان پارامتر به آن ارسال شده اند قابلیت تغییر دارند، از اینرو درون این متدهایی که به آنها ارسال می شوند، قبل از اینکه بتوان از آنها استفاده نمود باید مقداری به آنها تخص یص داده شود . اولین خط در متد modifyAddress() بصورت توضیحات نوشته شده است . این خط را از حالت توضیحات خارج کرده و سپس برنامه اجرا کنید تا ببینید چه اتفاقی رخ خواهد داد . هنگامیکه این پارامتر مقدار دهی شود و مقداری را به متد فراخواننده خود بازگرداند، این مقدار بر روی متغیر متد فراخواننده کپی می گردد . توجه نمایید که پارامترهای out میبایست قبل از دستور return درون متد مقدار دهی شده باشند .
یکی از ویژگیهای مفید زبان C# ، وجود پارامترهای params است که بوسیله آنها می توان متدی را اعلان کرد که تعداد متغیری متغیر را به عنوان پارامتر دریافت نماید . پارامترهای params حتماً باید یکی از انواع آرایه تک بعدی و یا آرایه دندانهدار (Jagged Array) باشند . در متد makeDecision() چهار متغیر رشته ای را به متد viewAddresses() ارسال نموده ایم که این متد
پارامترهای خود را بصورت params دریافت می نماید . همانطور که ملاحظه می نمایید، تعداد متغیرهای ارسالی به متد می تواند متغیر باشد اما دقت داشته باشید که تمامی این متغیرها در یک آرایه تک بعدی قرار گرفت ه اند . درون متد viewAddresses() نیز با استفاده از دستور foreach تمامی عناصر موجود در این آر ایه را نمایش داده ایم . پارامترهای params فقط متغیرهای ورودی دریافت مینمایند و تغییرات اعمال شده تنها بر روی متغیر محلی تاثیر میگذارد .
 
خلاصه
در این درس، با ساختار کلی یک متد آشنا شدی د . فرا گرفتید که در زبان C# چهار نوع پارامتر برای متدها وجود دارند . پارامترهای value، ref ، out و . params همانطور که گفته شد حالت پیش فرض برای پارامترها، value است مگر آنکه صریحاً مشخص گردد .

www.IrAnpRoje.com

Copyright © 2014 icbc.ir