فراخوانی متدها به روش ارجاع
نام دوره: زبان سی شارپ مقدماتی
نویسنده: علی مقدم جاه (مدرس دوره)
فراخوانی متدها به روش ارجاع
در پست آموزش متد چیست، با تعریف متد به همراه ساختار آن آشنا شدهاید.
درنتیجه قطعا میدانید که اگر یک متد دارای ورودی باشد، آن ورودی به طور کلی به ۳ روش برای متد ارسال خواهد شد:
- روش Extension
- روش استفاده از شناسه متغیر
- روش استفاده مستقیم از داده یا همان مقدار
روش Extension که بحث دیگری دارد و مربوط به این پست نیست، اما روشهای ۲ و ۳ یعنی چی؟
برای اینکه راحتتر متوجه شوید، ابتدا یک متد به نام Sum تعریف میکنیم:
public int Sum(int a)
{
return a + 10;
}
حال برای ارسال ورودی به این متد، دو روش کلی وجود دارد:
روش اول: استفاده مستقیم از داده یا همان مقدار
int num = Sum(2);
:خروجی
num = 12
روش دوم: استفاده از شناسه متغیر
int number = 2;
int num = Sum(number);
:خروجی
num = 12
پس یا مقدار را بصورت مستقیم در داخل پرانتز متد مینویسیم، یا ابتدا یک متغیر مثل number تعریف کرده و پس از درج مقدار درون این ظرف، شناسه متغیر را به عنوان ورودی داخل پرانتز متد Sum مینویسیم.
در حالت دوم، یک نکته مهم وجود دارد، آن هم این است که ابتدا سیستم یک کپی از متغیر number گرفته و آن کپی را برای متد Sum ارسال میکند!
به همین علت اگر هر تغییری متد Sum بر روی ورودی خود که شناسه number است ایجاد کند، بر روی متغیر int number، به هیچ عنوان آن تغییرات اعمال نمیشود!
به کد زیر دقت کنید:
int number = 2;
int num = Sum(number);
Console.WriteLine(number);
:خروجی
num = 12
number = 2
اگر کد بالا را در IDE خود اجرا کنید، مشاهده میکنید که متد WriteLine برای شما عدد ۲ را چاپ میکند!
چون سیستم ابتدا عدد ۲ که درون متغیر number بوده را یک نسخه کپی گرفته، و سپس کپی گرفته شده از آن ۲ را به متد Sum به عنوان ورودی ارسال میکند.
در نتیجه وقتی بعد از دستور ;int num = Sum(number) با استفاده از متد WriteLine آمدیم و مقدار number را چاپ کردیم، مشاهده کردیم که همچنان number را ۲ چاپ میکند، با وجود آنکه number در متد Sum تبدیل به عدد ۱۲ شده است!
درنتیجه هر زمان که خواستیم تغییرات داخل متدها مستقیما بر روی مقادیر اصلی ما تاثیر نگذارند، میتوانیم از روش دوم استفاده کنیم.
اما خیلی اوغات پیش میآید که شما نیاز دارید تا تغییرات متد، بر روی متغیر شما نیز تاثیر بگذارد!
یعنی در همین مثال بالا، میخواهید پس از آنکه متغیر number را به عنوان ورودی به متد Sum ارسال کردید که نتیجه آن عدد ۱۲ میشود، آن عدد ۱۲ درون متغیر int number ریخته شده و عدد ۲ حذف شود!
int number = 2;
int num = Sum(number);
Console.WriteLine(number);
:خروجی
num = 12
number = 12
یعنی در این حالت متد WriteLine عدد ۱۲ را چاپ کند، چون دیگر یک نسخه کپی برای متد Sum ارسال نشده و دقیقا همان نسخه اصلی number به عنوان ورودی به متد Sum ارسال شده است.
برای اینکار بایستی تا از فراخوانی به روش ارجاع استفاده کنید.
در فراخوانی به روش ارجاع، نسخه اصلی متغیرها به عنوان ورودی به متد ارسال شده و هر تغییری که درون بلاک متد بر روی آن ورودی بوجود آید، مستقیما بر روی نسخه اصلی متغیر نیز انجام میشود.
برای اینکه از فراخوانی به روش ارجاع استفاده کنید، باید در هنگام تعریف متد، قبل از مشخص کردن متغیرهای ورودی متد، از دو کلمه ref و out استفاده کنید.
الف) کلمه کلیدی ref
از کلمه کلیدی ref زمانی استفاده میکنیم که متغیر نسخه اصلی ما دارای ورودی باشد! مثل همین مثال بالا که int number برابر ۲ بود، درنتیجه بخاطر وجود عدد ۲، این متغیر دارای مقدار است!
public int Sum(ref int a)
{
return a + 10;
}
همانطور که در مثال بالا مشاهده میکنید، ما در هنگام تعریف متد Sum برای ورودی متد که متغیر int a است، ابتدا کلمه کلیدی ref را نوشتهایم، با اینکار هر زمان که شناسه یک متغیر به عنوان ورودی به متد Sum ارسال شود، تغییرات بر روی نسخه اصلی آن متغیر نیز اعمال خواهد شد:
int number = 2;
int num = Sum(number);
Console.WriteLine(number);
:خروجی
num = 12
number = 12
درنتیجه مقدار قبلی درون متغیر int number پاک شده و مقدار جدید که از متد Sum تولید میشود، درون متغیر int number ذخیره میشود.
ب) کلمه کلیدی out
از کلمه کلیدی out زمانی استفاده میکنیم که متغیر نسخه اصلی ما دارای ورودی نباشد! مثل int number;
یعنی فقط تعریف شده و هنوز هیچ مقدار یا همان دادهای داخل آن درج نشده است.
نکته مهم: در هنگام استفاده از کلمه کلیدی out، باید درون متد خود، ابتدا یک مقدار بی اثر را برای متغیر مشخص کنید!
public int Sum(out int a)
{
int a = 0;
return 5 + 10;
}
همانطور که در مثال بالا مشاهده میکنید، ما در هنگام تعریف متد Sum برای ورودی متد که متغیر int a است، ابتدا کلمه کلیدی out را نوشته و سپس درون محدوده بلاک متد، برای متغیر int a یک مقدار صفر که در عملیات جمع بی اثر است را مشخص کردهایم؛ با اینکار هر زمان که شناسه یک متغیر به عنوان ورودی به متد Sum ارسال شود، تغییرات به صورت مستقیم درون نسخه اصلی متغیر ذخیره خواهد شد.
int number;
int num = Sum(number);
Console.WriteLine(number);
:خروجی
num = 15
number = 15
برای درک بهتر مبحث فراخوانی به روش ارجاع، قطعه کدی را برایتان آماده کردهایم که بارها در برنامههای خود از آن استفاده نمودهاید:
Console.Write("Enter number: ");
int number;
while (!int.TryParse(Console.ReadLine(), out number))
{
Console.WriteLine("Warning!!!\tjust number");
}
Console.WriteLine("Number is : {0}", number);
این قطعه کد بسیار کاربردیای است، در این کد ابتدا از کاربر درخواست ورودی از نوع عددی میشود، اما با استفاده از حلقه while شرطی گذاشتهایم به عنوان تا زمانی که کاربر تنها کاراکتر عدد وارد نکرده، به او پیغام Warning داده و مجدد از او درخواست کند تا عدد وارد کند، درصورتی که کاربر بالاخره تصمیم گرفت عددی را به عنوان ورودی وارد کنید، آن ورودی از نوع عدد دریافت شده و با استفاده از کلمه کلیدی out درون متغیر number ذخیره میکند.
جهت شرکت در دورههای زبان برنامه نویسی سیشارپ، از کد تخفیف heplc30 استفاده کنید.