Theory and Tasks for Students - Spring 2019
Методы

Методы можно рассматривать как функции, позволяющие разделять код программы на логические части и повторно использовать блоки кода без копирования-вставки. Методы - члены класса и оформляются определённым способом: возвращаемый_тип ИмяМетода(тип_аргумента_1 имя_аргумента_1, тип_арг_2 имя_арг_2, ...) { //---тело метода }

Пока что в консольных приложениях мы используем лишь один класс - Program, в котором уже имеется один метод - Main. В дополнение к нему методы оформляются следующим образом: using System; using System.Collections.Generic; using System.Text; using System.IO; namespace ExampleApp { class Program { static double Func(double x) { return x * x + 2 * x - 9; } static void Print(int[] arr) { foreach (var elem in arr) { Console.Write("{0} ", elem); } Console.WriteLine(); } static void Main(string[] args) { //---your code goes here } } } Обратите внимание на слово static - в нашем случае оно обязательно, о его значении будет рассказано значительно позже.

Итак, в примере выше, метод Func принимает в качестве аргумента одно вещественное число. Его значение будет содержаться в локальной переменной x - это значит, что она уже описана и существует в пределах фигурных скобок(тела) метода. Этот метод возвращает значение типа double - значит, при завершении работы метода это значение должно быть определено. Это делается с помощью оператора return, после которого следует выражение, значение которого и станет результатом работы функции. static void Main(string[] args) { double y = Func(2); //в y будет занесено -1 double a = 1; double res = Func(a); //в res будет занесено -6 } Выполнение оператора return сразу завершает работу метода. Каждая ветвь кода в методе должна возвращать значение, если возвращаемый тип не указан как void - пустота. Такие методы обычно предназначены для совершения каких-либо действий над другими объектами, например, вывода значений в консоль - метод Print из примера выше выводит переданный ему массив в консоль. Использовать оператор return в данном случае ненужно.

Важно помнить, что разные типы данных ведут себя по-разному, когда используются в качестве аргументов. Значимые типы данных - базовые типы: int, double, char, bool и другие структуры) - передаются по значению, т.е. значение переменной, переданной в качестве фактического параметра - a в Func(a) - копируется в переменную-аргумент в методе. Ссылочные типы данных - массивы, строки и вообще классы, в т.ч. object - передаются по ссылке, т.е. переменная-аргумент ссылается на тот же самые объект, что и фактические параметр. Таким образом если в методе Print(myArr) будут производиться изменения с массивом arr, то изменится и массив по ссылке в myArr. Это позволяет создавать методы, например, заполняющие массивы: static void RandomizeArray(int[] arr) { Random rnd = new Random(); for (int i = 0; i < arr.Length; i++) { arr[i] = rnd.Next(0, 101); } } static void Main(string[] args) { int[] myArr = new int[10]; RandomizeArray(myArr); }

Все аргументы методов являются обязательными. К ним в конец можно добавлять необязательные аргументы, задавая им значение по умолчанию: static void PrintPretty(int[] arr, string separator = " ") { Console.Write(arr[0]); for (int i = 1; i < arr.Length; i++) { Console.Write("{0}{1}", separator, arr[i]); } Console.WriteLine(); } static void Main(string[] args) { int[] arr = [1, 2, 3, 4]; PrintPretty(arr); //1 2 3 4 PrintPretty(arr, ", "); //1, 2, 3, 4 }

После всех необязательных аргументов можно указать ещё один аргумент динамического размера params. Он позволяет методу принимать любое число аргументов одного типа - они все будут записаны в массив: //---принимает 2 или больше чисел static int MyMax(int a, int b, params int[] other) { int max = a; if (b > max) { max = b; } foreach (var elem in other) { if (elem > max) { max = elem; } } return max; } static void Main(string[] args) { int max1 = MyMax(1, 4); //4 int max2 = MyMax(1, 2, 5, 60, -2, 12); //60 }