Energy
education

сайт для тех, кто хочет изучать энергетику

11. Методы

Метод представляет собой группу операторов, которые предназначены для выполнение определенной задачи. Каждая программа на языке C# имеет как минимум один класс с методом Main.

Для того, чтобы мспользовать методы необходимо:

  • Определить метод
  • Вызвать метод

Определение методов в C#

Когда вы определяете метод, вы по сути, объявляете элементы его структуры. Синтаксис для определения метода в C# следующий:

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

Ниже приведены различные элементы метода:

  • Спецификатор доступа: Необходим для определения видимости переменных или методов для других классов.
  • Возвращаемый тип: Метод может возвращать значение. Тип возвращаемого значения это тип данных для возвращаемого значения метода. Если метод не возвращает значение, тогда тип возвращаемоего значения будет void.
  • Имя метода: Имя метода это уникальный индитификатор и он регистрозависимый.
  • Список параметров: Записаные в скобках параметры используются для передачи и получения данных в метод и из него. Список параметров включет описание типа, порядка и количества параметров метода. Параметры являются необязательными, то есть метод может не иметь параметров.
  • Тело метода: Содержит набор инструкций, необходимых для завершения требуемой операции.

Пример:

Следующий фрагмент кода показывает метод FindMax, который принимает два целочисленных значений и возвращает большее из них. Он имеет спецификатор доступа public , поэтому он может быть доступен вне класса с помощью экземпляра класса.

    
class NumberManipulator
{
   public int FindMax(int num1, int num2)
   {
      /* объявление локальной переменной */
      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)
      {
         /* объявление локальной переменной */
         int result;
         if (num1 > num2)
            result = num1;
         else
            result = num2;
         return result;
      }
      static void Main(string[] args)
      {
         /* объявление локальных переменных */
         int a = 100;
         int b = 200;
         int ret;
         NumberManipulator n = new NumberManipulator();
         //вызов метода FindMax
         ret = n.FindMax(a, b);
         Console.WriteLine("Максимальное значение : {0}", ret );
         Console.ReadLine();
      }
   }
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату:

    
Максимальное значение : 200
    

Также можно вызывать методы со спецификатором доступа public из других классов с помощью экземпляра класса. Например, метод FindMax принадлежит классу NumberManipulator. Его можно вызвать из другого класса Test.

    
using System;
namespace CalculatorApplication
{
    class NumberManipulator
    {
        public int FindMax(int num1, int num2)
        {
            /* объявление локальной переменной */
            int result;
            if (num1 > num2)
                result = num1;
            else
                result = num2;
            return result;
        }
    }
    class Test
    {
        static void Main(string[] args)
        {
            /* объявление локальных переменных */
            int a = 100;
            int b = 200;
            int ret;
            NumberManipulator n = new NumberManipulator();
            //вызов метода FindMax
            ret = n.FindMax(a, b);
            Console.WriteLine("Максимальное значение : {0}", ret );
            Console.ReadLine();
        }
    }
}
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату:

    
Максимальное значение : 200
    

Рекурсивный вызов метода

Метод может вызывать сам себя. Это называется рекурсия. Следующий пример программы для вычисления факториала для заданного чискла использует рекурсивный метод:

    
using System;
namespace CalculatorApplication
{
    class NumberManipulator
    {
        public int factorial(int num)
        {
            /* объявление локальной переменной */
            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
            Console.WriteLine("Факториал 6 : {0}", n.factorial(6));
            Console.WriteLine("Факториал 7 : {0}", n.factorial(7));
            Console.WriteLine("Факториал 8 : {0}", n.factorial(8));
            Console.ReadLine();
        }
    }
}
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату:

    
Факториал 6 : 720
Факториал 7 : 5040
Факториал 8 : 40320
    

Передача параметров в метод

Когда вызывается метод с параметрами, необходимо передать параметры методу. В C# есть три способа передать параметры методу:

МеханизмОписание
Значенияэтот способ копирует действительное значение аргумента в формальный параметр метода. В этом случае, изменение параметра внутри метода не влияют на значение аргумента.
СсылкиЭтот способ копирует ссылки на область памяти где расположен аргумент в формальный параметр метода. Это означает что изменение параметра влияют на аргумент.
Выходные параметрыВ этом случае можно вернуть несколько значений.

Передача параметров по значению

Это самый распространеный механизм передачи параметров в метод. В этом случае, когда метод вызывается, создается копия для каждого из передаваемых парамеров. В этом случае, изменение параметра внутри метода не влияют на значение аргумента. Следующий пример демонстрирует это:

    
using System;
namespace CalculatorApplication
{
    class NumberManipulator
    {
        public void swap(int x, int y)
        {
            int temp;
            temp = x; /* сохраняет значение x */
            x = y;    /* помещает значение y в x */
            y = temp; /* помещает значение temp в y */
        }
    
        static void Main(string[] args)
        {
            NumberManipulator n = new NumberManipulator();
            /* объявление локальных переменных */
            int a = 100;
            int b = 200;
            Console.WriteLine("До замены, значение a : {0}", a);
            Console.WriteLine("До замены, значение b : {0}", b);
            /* вызыв метода swap */
            n.swap(a, b);
            Console.WriteLine("После замены, значение a : {0}", a);
            Console.WriteLine("После замены, значение b : {0}", b);
 
            Console.ReadLine();
        }
    }
}
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату:

    
До замены, значение of a :100
До замены, значение of b :200
После замены, значение of a :100
После замены, значение of b :200
    

Это показывает, что никаких изменений значений не произошло, даже при изменении их значений внутри метода.

Передача параметров по ссылке

Параметр ссылка это ссылка на область памяти переменной. Когда вы передаете параметр в качестве ссылки, в отличие от передачи значения, новая копия не создается. Параметр ссылка ссылается на ту же область памяти где содержиться значение параметра передпваемого в метод.

В C# объявление параметра ссылки происходит использыя ключевое слово ref. Следующий пример демонстрирует это:

    
using System;
namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void swap(ref int x, ref int y)
      {
         int temp;
            temp = x; /* сохраняет значение x */
            x = y;    /* помещает значение y в x */
            y = temp; /* помещает значение temp в y */
       }
   
      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* объявление локальных переменных */
         int a = 100;
         int b = 200;
         Console.WriteLine("До замены, значение a : {0}", a);
         Console.WriteLine("До замены, значение b : {0}", b);
         /* вызыв метода swap */
         n.swap(ref a, ref b);
         Console.WriteLine("После замены, значение a : {0}", a);
         Console.WriteLine("После замены, значение b : {0}", b);
 
         Console.ReadLine();
      }
   }
}
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату:

    
До замены, значение a : 100
До замены, значение b : 200
После замены, значение a : 200
После замены, значение b : 100
    

Это показывает, что значения параметров изменились внутри метода swap и эти изменения отразидись в методе Main.

Передача выходных параметров

Оператор 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();
         /* объявление локальной переменной */
         int a = 100;
         
         Console.WriteLine("До вызова метода, значение a : {0}", a);
         
         /* вызов метода getValue */
         n.getValue(out a);
         Console.WriteLine("После вызова метода, значение a : {0}", a);
         Console.ReadLine();
      }
   }
}
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату:

    
До вызова метода, значение a : 100
После вызова метода, значение a : 5
    

Несмотря на то, что переменные, передаваемые в качестве выходных параметров могут не инициализироваться перед передачей, вызывающий метод должен присвоить значение перед возвратом метода. Выходные параметры особенно полезны когда необходимо вернуть значения из метода через параметры без инициализаций значений параметров. Посмотрите следующий пример, чтобы понять это:

    
using System;
namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void getValues(out int x, out int y )
      {
          Console.WriteLine("Введите первое значение: ");
          x = Convert.ToInt32(Console.ReadLine());
          Console.WriteLine("Введите второе значение: ");
          y = Convert.ToInt32(Console.ReadLine());
      }
   
      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* объявление локальной переменной */
         int a , b;
         
         /* вызов метода getValues */
         n.getValues(out a, out b);
         Console.WriteLine("После вызова метода, значение a : {0}", a);
         Console.WriteLine("После вызова метода, значение b : {0}", b);
         Console.ReadLine();
      }
   }
}
    

Если приведенный выше код скомпилировать и выполнить, это приведет к следующему результату (в зависимости от ввода пользователя):

    
Введите первое значение:
7
Введите второе значение:
8
После вызова метода, значение a : 7
После вызова метода, значение b : 8