سه شنبه ۲۷ شهريور ۱۴۰۳
Tut24 آموزش برنامه نویسی و مجله تخصصی فناوری ورود/عضویت

آموزش سی شارپ - متدها

متد، گروهی از دستورات است که برای انجام یک وظیفه مشخص تعریف می شوند. هر برنامه C# حداقل یک کلاس با یک متد به نام Main دارد.

برای استفاده از یک متد، شما باید −

  • متد را تعریف کنید
  • متد را صدا بزنید

تعریف متدها در C#

زمانی که یک متد را تعریف می‌کنید، در واقع عناصر ساختار آن را اعلام می‌کنید. سینتکس تعریف متد در C# به شرح زیر است −

<Access Specifier> <Return Type> <Method Name>(Parameter List) {
   Method Body
}

عناصر مختلف یک متد به شرح زیر می‌باشد −

  • Access Specifier (مشخص‌کننده دسترسی) − این مورد دسترسی به یک متغیر یا متد را از یک کلاس دیگر تعیین می‌کند.

  • Return type (نوع بازگشت) − یک متد ممکن است یک مقدار را بازگرداند. نوع بازگشت نوع داده‌ای مقداری است که متد برمی‌گرداند. اگر متد هیچ مقداری را باز نمی‌گرداند، آنگاه نوع بازگشت void است.

  • Method name (نام متد) − نام متد یک شناسه منحصر به فرد است و حساس به بزرگی و کوچکی حروف است. نمی‌تواند مشابه با هر شناسه دیگری در کلاس باشد.

  • Parameter list (لیست پارامترها) − بین پرانتزها، پارامترها برای گذراندن و دریافت داده از یک متد استفاده می‌شوند. لیست پارامترها به نوع، ترتیب و تعداد پارامترهای یک متد اشاره دارد. پارامترها اختیاری هستند؛ به عبارت دیگر، یک متد ممکن است حاوی هیچ پارامتری نباشد.

  • Method body (بدنه متد) − این حاوی مجموعه دستورات مورد نیاز برای انجام فعالیت مورد نظر است.

مثال

کد زیر نمونه یک تابع با نامFindMax را نشان می‌دهد که دو مقدار صحیح را دریافت کرده و بزرگترین آن دو را باز می‌گرداند. این تابع دارای دسترسی عمومی (public) است، بنابراین می‌توان از خارج از کلاس با استفاده از یک نمونه (instance) از کلاس به آن دسترسی داشت.

class NumberManipulator {

   public int FindMax(int num1, int num2) {
      /* local variable declaration */
      int result;

      if (num1 > num2)
         result = num1;
      else
         result = num2;

      return result;
   }
   ...
}

فراخوانی متدها در C#

شما می‌توانید با استفاده از نام متد، آن را فراخوانی کنید. مثال زیر این موضوع را نمایش می‌دهد −

using System;

namespace CalculatorApplication {
   class NumberManipulator {
      public int FindMax(int num1, int num2) {
         /* local variable declaration */
         int result;
         
         if (num1 > num2)
            result = num1;
         else
            result = num2;
         return result;
      }
      
      static void Main(string[] args) {
         /* local variable definition */
         int a = 100;
         int b = 200;
         int ret;
         NumberManipulator n = new NumberManipulator();

         //calling the FindMax method
         ret = n.FindMax(a, b);
         Console.WriteLine("Max value is : {0}", ret );
         Console.ReadLine();
      }
   }
}

وقتی کد بالا کامپایل و اجرا می‌شود، نتیجه زیر تولید می‌شود −

Max value is : 200

شما همچنین می‌توانید از طریق نمونه کلاس، متد عمومی را از کلاس‌های دیگر فراخوانی کنید. به عنوان مثال، متد FindMax به کلاس NumberManipulator تعلق دارد، می‌توانید آن را از یک کلاس دیگر به نام Test فراخوانی کنید.

using System;

namespace CalculatorApplication {
   class NumberManipulator {
      public int FindMax(int num1, int num2) {
         /* local variable declaration */
         int result;
         
         if(num1 > num2)
            result = num1;
         else
            result = num2;
         
         return result;
      }
   }
   class Test {
      static void Main(string[] args) {
         /* local variable definition */
         int a = 100;
         int b = 200;
         int ret;
         NumberManipulator n = new NumberManipulator();
         
         //calling the FindMax method
         ret = n.FindMax(a, b);
         Console.WriteLine("Max value is : {0}", ret );
         Console.ReadLine();
      }
   }
}

هنگامی که کد بالا کامپایل و اجرا می شود، نتیجه زیر را ایجاد می کند -

Max value is : 200

فراخوانی بازگشتی متد (Recursive Method Call)

یک متد می تواند خودش را صدا کند. این به عنوان بازگشتی شناخته می شود. مثال زیر، محاسبه فاکتوریل برای یک عدد داده شده با استفاده از یک تابع بازگشتی را نشان می دهد −

using System;

namespace CalculatorApplication {
   class NumberManipulator {
      public int factorial(int num) {
         /* local variable declaration */
         int result;
         if (num == 1) {
            return 1;
         } else {
            result = factorial(num - 1) * num;
            return result;
         }
      }
      static void Main(string[] args) {
         NumberManipulator n = new NumberManipulator();
         //calling the factorial method {0}", n.factorial(6));
         Console.WriteLine("Factorial of 7 is : {0}", n.factorial(7));
         Console.WriteLine("Factorial of 8 is : {0}", n.factorial(8));
         Console.ReadLine();
      }
   }
}

هنگامی که کد فوق کامپایل و اجرا می‌شود، نتیجه زیر را تولید می‌کند −


Factorial of 6 is: 720
Factorial of 7 is: 5040
Factorial of 8 is: 40320

انتقال پارامترها به یک متد

وقتی که یک متد با پارامتر صدا زده می‌شود، باید پارامترها به متد ارسال شوند. سه روش برای انتقال پارامترها به یک متد وجود دارد −

ردیف مکانیزم و توضیحات
۱ پارامترهای مقدار

در این روش، مقدار واقعی یک آرگومان به پارامتر فرمال متد کپی می‌شود. در این حالت، تغییراتی که در پارامتر داخل متد انجام می‌شود بر روی آرگومان تاثیری ندارد.

۲ پارامترهای مرجع

در این روش، مرجع حافظه یک آرگومان به پارامتر فرمال متد کپی می‌شود. به این معنی که تغییراتی که در پارامتر اعمال می‌شود بر روی آرگومان تاثیر می‌گذارد.

۳ پارامترهای خروجی

این روش برای برگرداندن بیش از یک مقدار استفاده می‌شود.

انتقال پارامترها به متد در C# به وسیله مقدار

این مکانیزم پیش‌فرض برای انتقال پارامترها به یک متد است. در این مکانیزم، هنگامی که یک متد فراخوانی می‌شود، برای هر پارامتر مقدار یک مکان ذخیره‌سازی جدید ایجاد می‌شود.

مقادیر پارامترهای واقعی در آن‌ها کپی می‌شوند. بنابراین، تغییراتی که درون متد بر روی پارامتر اعمال می‌شوند، بر روی آرگومان تاثیری ندارند. مثال زیر این مفهوم را نشان می‌دهد −

using System;

namespace CalculatorApplication {
   class NumberManipulator {
      public void swap(int x, int y) {
         int temp;
         
         temp = x; /* save the value of x */
         x = y;    /* put y into x */
         y = temp; /* put temp into y */
      }
      static void Main(string[] args) {
         NumberManipulator n = new NumberManipulator();
         
         /* local variable definition */
         int a = 100;
         int b = 200;
         
         Console.WriteLine("Before swap, value of a : {0}", a);
         Console.WriteLine("Before swap, value of b : {0}", b);
         
         /* calling a function to swap the values */
         n.swap(a, b);
         
         Console.WriteLine("After swap, value of a : {0}", a);
         Console.WriteLine("After swap, value of b : {0}", b);
         
         Console.ReadLine();
      }
   }
}

پس از کامپایل و اجرای کد بالا، نتیجه زیر تولید می شود −


Before swap, value of a :100
Before swap, value of b :200
After swap, value of a :100
After swap, value of b :200

این نشان می‌دهد که مقادیر تغییری نکردند، هرچند که در داخل تابع تغییر کرده بودند.

انتقال پارامترها در C# به وسیله مرجع (Passing Parameters by Reference)

پارامتر مرجع (Reference Parameter)، یک مرجع به مکان حافظه‌ای از یک متغیر است. وقتی پارامترها را با استفاده از مرجع منتقل می‌کنید، در مقابل پارامترهای مقدار، یک مکان ذخیره‌سازی جدید برای این پارامترها ایجاد نمی‌شود. پارامترهای مرجع نشان‌دهنده همان مکان حافظه‌ای هستند که پارامترهای واقعی که به متد داده می‌شوند نشان می‌دهند.

شما می‌توانید با استفاده از کلیدواژه ref، پارامترهای مرجع را اعلام کنید. مثال زیر این مفهوم را نشان می‌دهد −

using System;

namespace CalculatorApplication {
   class NumberManipulator {
      public void swap(ref int x, ref int y) {
         int temp;

         temp = x; /* save the value of x */
         x = y;    /* put y into x */
         y = temp; /* put temp into y */
      }
      static void Main(string[] args) {
         NumberManipulator n = new NumberManipulator();
         
         /* local variable definition */
         int a = 100;
         int b = 200;

         Console.WriteLine("Before swap, value of a : {0}", a);
         Console.WriteLine("Before swap, value of b : {0}", b);

         /* calling a function to swap the values */
         n.swap(ref a, ref b);

         Console.WriteLine("After swap, value of a : {0}", a);
         Console.WriteLine("After swap, value of b : {0}", b);
 
         Console.ReadLine();
      }
   }
}

وقتی کد بالا کامپایل و اجرا می‌شود، نتیجه زیر تولید می‌شود −

Before swap, value of a : 100
Before swap, value of b : 200
After swap, value of a : 200
After swap, value of b : 100

این نشان می‌دهد که مقادیر داخل تابع swap تغییر کرده‌اند و این تغییر در تابع Main بازتاب داده شده است.

C# - انتقال پارامترها به صورت خروجی

یک دستور return فقط برای بازگرداندن یک مقدار از یک تابع استفاده می‌شود. با استفاده از پارامترهای خروجی، شما می‌توانید دو مقدار را از یک تابع بازگردانید. پارامترهای خروجی شبیه به پارامترهای مرجع هستند، با این تفاوت که داده‌ها را از تابع خارج می‌کنند به جای آنکه به آنجا منتقل کنند.

مثال زیر این را نشان می‌دهد −

using System;

namespace CalculatorApplication {
   class NumberManipulator {
      public void getValue(out int x ) {
         int temp = 5;
         x = temp;
      }
      static void Main(string[] args) {
         NumberManipulator n = new NumberManipulator();
         
         /* local variable definition */
         int a = 100;
         
         Console.WriteLine("Before method call, value of a : {0}", a);
         
         /* calling a function to get the value */
         n.getValue(out a);

         Console.WriteLine("After method call, value of a : {0}", a);
         Console.ReadLine();
      }
   }
}

زمانی که کد بالا کامپایل و اجرا می‌شود، نتیجه زیر را تولید می‌کند −


Before method call, value of a : 100
After method call, value of a : 5

متغیر ارسال شده برای پارامتر خروجی نیازی به اختصاص مقدار ندارد. پارامترهای خروجی بسیار مفید هستند زمانی که نیاز دارید مقادیری را از یک متد از طریق پارامترها برگردانید بدون اختصاص دادن مقدار اولیه به پارامتر. برای درک این موضوع، به مثال زیر بروید −

using System;

namespace CalculatorApplication {
   class NumberManipulator {
      public void getValues(out int x, out int y ) {
          Console.WriteLine("Enter the first value: ");
          x = Convert.ToInt32(Console.ReadLine());
          
          Console.WriteLine("Enter the second value: ");
          y = Convert.ToInt32(Console.ReadLine());
      }
      static void Main(string[] args) {
         NumberManipulator n = new NumberManipulator();
         
         /* local variable definition */
         int a , b;
         
         /* calling a function to get the values */
         n.getValues(out a, out b);
         
         Console.WriteLine("After method call, value of a : {0}", a);
         Console.WriteLine("After method call, value of b : {0}", b);
         Console.ReadLine();
      }
   }
}

پس از کامپایل و اجرای کد بالا، نتیجه زیر تولید می شود −

Enter the first value:
7
Enter the second value:
8
After method call, value of a : 7
After method call, value of b : 8