هر برنامهنویسی چه آماتور و چه پیشرفته تا به حال نام تابع را شنیده است. توابع در تمام زبانهای برنامهنویسی وجود دارند و از بخشهای جدانشدنی یک برنامه هستند. به خصوص در زبانهایی مثل پایتون، جاوا و #C که جزو زبانهای برنامهنویسی مبتنی بر شیگرایی هستند، از توابع استفاده زیادی میشود. در این بخش از آموزشهای زبان برنامهنویسی سیشارپ، درباره توابع در c# یا همان متدها بحث خواهیم کرد.
ساختار توابع در c#
1 2 3 4 5 |
returnType MethodName (parameterType parameterName , ....) { statements; } |
متدها در #C داخل کلاس تعریف میشوند و دارای یک مجموعه از پارامتر های ورودی هستند که بین پرانتز ها بعد از نام تابع میآیند. متدها دارای یک مقدار برگشتی نیز میباشند. اگر تابع ما دارای خروجی نباشد، باید از کلمه کلیدی void استفاده کرد. برای نامگذاری توابع در c# از روش پاسکال (اول حرف هر کلمه بزرگ نوشته میشود) استفاده میکنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { PrintWelcome(); } static void PrintWelcome() { Console.WriteLine("Welcome"); } } } |
1 2 |
Welcome |
همانطور که مشاهده میکنید قبل از متد Main در محیط کنسول از کلمه کلیدی static استفاده شده است. این کلمه به ما میگوید که متدها و متغیرهایی که میخواهند در این تابع به کار گرفته شوند باید از نوع static باشند. ما در بخش شیگرایی بیشتر راجع به این مطلب بحث خواهیم کرد. برای این که متد PrintWelcome (به نام متد توجه کنید) استاتیک تعریف شود ، قبل از returnType از کلمه کلیدی static استفاده کردهایم. دقت کنید که فرقی ندارد، تابع ساخته شده قبل و یا بعد از متد Main قرار گیرد.
پارامترها و آرگومانها
در تعریف توابع در c# بین پرانتزها، پارامترها قرار میگیرند. هر تعداد پارامتر نیاز باشد میتوان تعریف کرد. به مقادیری که به پارامترها در هنگام استفاده از متد داده میشود، آرگومان میگویند. در مثال زیر دو مقدار را به تابع داده و حاصل جمع آنها را چاپ میکنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { int number1 = 5; int number2 = 12; Sum(number1, number2); } static void Sum(int num1, int num2) { int result = num1 + num2; Console.WriteLine("Result = {0}", result); } } } |
1 2 |
Result = 17 |
ترتیب ارسال آرگومان به پارامترها فوقالعاده مهم است و اگر رعایت نشود باعث خطای منطقی خواهد شد. در مثال بالا این نکته مشهود نیست؛ چون دو پارامتر از نوع int هستند و عملگر جمع نیز خاصیت جابهجایی دارد. مثال زیر این نکته را به خوبی نشان میدهد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { int number = 5; string str = "HelloWorld"; Show(number, str); } static void Show(int num, string str) { Console.WriteLine(str); Console.WriteLine(num); } } } |
1 2 3 |
HelloWorld 5 |
مثال فوق به خوبی اجرا میشود اما کامپایلر در اجرای تکه برنامهی زیر خطا میدهد؛ زیرا ترتیب ارسال آرگومان به پارامترها رعایت نشده است.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { int number = 5; string str = "HelloWorld"; Show(str, number); } static void Show(int num, string str) { Console.WriteLine(str); Console.WriteLine(num); } } } |
مقدار برگشتی از تابع
تا اینجای کار ما از تابع Main مقادیر را به تابعمان ارسال کردیم و در همان تابع نتایج را نشان دادیم. حال اگر بخواهیم نتایج پردازش را به تابع Main برگردانیم، باید تابع دارای نوع برگشتی باشد و از کلمه کلیدی return نیز به شکل زیر استفاده کنیم.
خطا ! لطفا دوباره تلاش کنید. |
1 2 |
Result = 22 |
متغیرهایی که در داخل متد تعریف میشوند (مانند resultSum) متغیر های محلی هستند و فقط در داخل همان تابع که تعریف شدهاند قابل استفاده هستند. مقدار برگشتی نیز میتواند دارای انواع دادهای مختلف باشد.
آرگومانهای کلمه کلیدی
استفاده از نام پارامترها برای ارسال آرگومان به پارامترها باعث میشود که ترتیب ارسال آرگومان به پارامترها را در نظر نگیریم. ولی در عوض باید نام پارامترها را حفظ کنیم ولی با توجه به Intellisense در ویژوال استودیو این مشکل حل شده است. ساختار آرگومانهای کلمه کلیدی در زیر آمده است.
1 2 3 4 |
// در هنگام فراخوانی تابع MethodName(parameterName : value1, parameterName : value2, ...); |
به مثال زیر توجه کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { int number1 = 55; int number2 = 17; string seq = "Result of Sum is equal = "; Sum(str: seq, num1: number1, num2: number2); } static void Sum(int num1, int num2, string str) { Console.WriteLine(str + "{0}", num1 + num2); } } } |
1 2 |
Result of Sum is equal = 72 |
ارسال آرگومان از طریق ارجاع
در همه مثالهای گفته شده از توابع در c#، آرگومانها از طریق مقدار به پارامترها اختصاص مییافتند. یعنی مقدار آرگومان در پارامتر کپی میشد. حال اگر بخواهیم وقتی مقدار پارامتر را در تابع تغییر میدهیم، مقدار آرگومان نیز در تابع فراخوانی کننده تغییر کند از روش ارسال از طریق ارجاع استفاده میکنیم. برای اینکار باید از کلمه کلیدی ref قبل از تعریف پارامتر استفاده کنیم.
1 2 3 4 5 |
returnType MethodName(ref dataType parameter, ...) { statement; } |
در فراخوانی نیز باید کلمه کلیدی ref را پشت نام آرگومان قرار دهیم.
1 2 |
MethodName(ref argumentName); |
به مثال زیر توجه کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { int number1 = 2; AddFive(ref number1); Console.WriteLine("Result = {0}", number1); } static void AddFive(ref int num) { num += 5; } } } |
1 2 |
Result = 7 |
همانطور که مشاهده میکنید متغیر number1 را به عنوان آرگومان به متد AddFive ارسال کردیم و در خط بعد مقدار متغیر number1 را نشان دادیم و مشاهده کردیم که مقدار پنج به آن اضافه شده است. در واقع پارامتر num نام مستعاری برای number1 است.
پارامترهای out
به پارامترهای out، متغیرهایی را به عنوان آرگومان اختصاص میدهیم که مقداردهی اولیه نشدهاند. استفاده از کلمه کلیدی out باعث ارسال آرگومان به روش ارجاع میشود؛ نه ارسال به روش مقدار. اگر بخواهیم متد مد نظرمان دارای چند خروجی باشد، از این کلمه کلیدی استفاده میکنیم. کلمه ref به کامپایلر میگوید آرگومان مقداردهی اولیه شده است ولی کلمه out این را نمیگوید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { int number1; AddFive(out number1); Console.WriteLine("Result = {0}", number1); } static void AddFive(out int num) { num = 5; } } } |
1 2 |
Result = 5 |
پارامترهای پیشفرض
به این دسته از توابع در c# هم میتوان آرگومان ارسال کرد و هم میتوان ارسال نکرد. پارامترهای این متدها دارای مقادیر پیشفرض هستند. در صورتی که آرگومان به آنها ارسال نشود از مقدار پیشفرض استفاده میکنند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { string name = "Naser"; int age = 15; int height = 170; Print(); Console.WriteLine("******************"); Print(name, age, height); } static void Print(string name = "", int age = 0, int height = 0) { Console.WriteLine($"Name is: {name}"); Console.WriteLine($"Height is: {height}" + "cm"); Console.WriteLine($"Age is: {age}"); } } } |
1 2 3 4 5 6 7 8 |
Name is: Height is: 0cm Age is: 0 ****************** Name is: Naser Height is: 170cm Age is: 15 |
همانطور که مشاهده میکنید وقتی آرگومان به تابع ارسال نمیشود، از مقادیر پیشفرض استفاده شده است. توجه کنید پارامترهایی که دارای مقدار پیشفرض هستند باید سمت راست بیایند.
1 2 3 4 |
void Print(string name = "", int age, int height = 0) //Error void Print(string name = "", int age, int height) //Error void Print(string name, int age = 0, int height = 0) //Correct |
ارسال آرایه به تابع
نکتهی بعدی این است که در هنگام استفاده از توابع در c# ، میتوان آرایه را به عنوان آرگومان به تابع ارسال کرد. فقط کافی است در هنگام تعریف متد از یک جفت کروشه بعد از نوع پارامتر استفاده کنیم. در هنگام فراخوانی نیز، فقط کافی است نام آرایه به متد ارسال شود. توجه کنید که ارسال آرایه به روش ارجاع است نه مقدار.
1 2 3 4 5 6 7 |
returnType MethodName(dataType[] parameterName) { statement; } /////////////////////////////////////////////// MethodName(arrayName); |
به مثال زیر توجه کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { int[] array = { 1, 2, 3, 4, 5, 6 }; Print(array); foreach (int item in array) { Console.WriteLine(item); } } static void Print(int[] ary) { for (int i = 0; i < ary.Length; i++) { ary[i] *= 10; } } } } |
1 2 3 4 5 6 7 |
10 20 30 40 50 60 |
خب دوستان این بخش هم به پایان رسید و امیدوارم مورد توجه قرار گرفته باشد مبحث بعدی شیگرایی میباشد. هرگونه سؤال یا مشکلی وجود داشت زیر همین پست کامنت بگذارید. تیم ما در کمترین زمان پاسخگوی شماست.