Содержание
Методы в C# – это именованная многократно используемая группа взаимосвязанных инструкций в коде, которые выполняют определенную задачу. Методы могут принимать в качестве входных данных различные значения и возвращать данные в качестве результата. На протяжение всего изучения C# мы уже множество раз использовали различные методы C#, а в этой части – научимся создавать пользовательские методы и использовать их в своих приложениях.
Методы в C#
Также, вы можете встретить такие названия как “процедуры”, “функции” и даже “модули”, но все эти понятия в C#, так или иначе, обозначают метод.
Зачем нужны методы в C#
Прежде, чем мы начнем детально разбираться с созданием и использованием методов в C#, стоит потратить немного времени и разобраться с вопросом: зачем нам вообще потребовались методы? Обычно, необходимость использования методов объясняется так: чтобы разделить код на взаимосвязанные части и использовать их. Однако, такое объяснение, по большому счёту, ничего и не объясняет. Ну разобьем мы код на части и что? Чтобы разобраться с тем, зачем нам потребовались методы в C#, давайте рассмотрим вот такой пример:
Console.ForegroundColor = ConsoleColor.DarkBlue;
Console.WriteLine("Привет, программист!");
Console.WriteLine("Код этого приложения прекрасно работает");
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WriteLine("И даже пишет в консоль текст разными цветами");
Console.WriteLine("И считает суммы чисел");
Console.ForegroundColor = ConsoleColor.White;
Console.Write("Введите первое число ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Введите второе число ");
int b = Convert.ToInt32(Console.ReadLine());
Console.WriteLine($"Сумма {a} + {b} = {a + b}");
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WriteLine("Видишь?");
Console.ForegroundColor = ConsoleColor.DarkMagenta;
Console.WriteLine("Давай попробуем ещё раз?");
Console.Write("Введите первое число ");
a = Convert.ToInt32(Console.ReadLine());
Console.Write("Введите второе число ");
b = Convert.ToInt32(Console.ReadLine());
Console.WriteLine($"Сумма {a} + {b} = {a + b}");
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WriteLine("И ещё раз");
Console.Write("Введите первое число ");
a = Convert.ToInt32(Console.ReadLine());
Console.Write("Введите второе число ");
b = Convert.ToInt32(Console.ReadLine());
Console.Write($"Сумма {a} + {b} = {a + b}");
Console.ForegroundColor = ConsoleColor.DarkBlue;
Console.WriteLine("Отличная программа!");
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Только трудно поддерживаемая и содержит много повторяющегося кода!");
Console.WriteLine("Для улучшения нам потребуются методы");
Console.ReadKey();
Можете скопировать этот код в новый проект Visual Studio и убедиться, что программа, действительно, работает:
Но даже в случае такой простой программы можно невольно допустить ошибку. Обратите внимание на строку где рассчитана последняя сумма чисел. Текст, написанный синим цветом должен был размещаться на следующей строке. Но это мелочи. Представим, что мы пишем программу, например, для банковского сектора где нам надо реализовать возможность расчёта сложных процентов, начислений по кредитам, выбор различных программ лояльности и прочее, прочее, прочее. И всё это будет написано так, как программа выше – как единый монолитный код. Как минимум мы столкнемся со следующим проблемами:
- Такой код будет трудночитаем.
- Такой код будет очень сложно поддерживать и модифицировать
- В конкретный момент времени над таки проектом сможет работать только один человек, а значит мы отказываемся от командной разработки.
Для решения этих проблем нам и необходимо понимать работу методов в C#. Мы ещё вернемся к коду представленной выше программы. А пока перейдем к рассмотрению темы “Методы в C#”
Как определяются методы в C#?
В самом общем случае, определение метода в C# выглядит следующим образом:
[спецификатор][модификаторы] тип_возвращаемого_значения Название_метода ([параметры])
{
тело метода
}
- Название метода является обязательным. Как и переменные, методы идентифицируются по имени. Правила присвоения имён методам такие же, как и правила присвоения имён переменным.
- Список параметров является необязательным и определяет то, какие данные принимает метод (то, что необходимо методу, чтобы выполнить возложенную на него задачу). Метод может принимать 0 или несколько параметров.
- Тип возвращаемого значения является обязательным. Метод может возвращать значение и тогда такой метод иногда называют функцией, а может ничего не возвращать и тогда такой метод могут называть процедурой. Если метод не должен возвращать никакого значения, то тип возвращаемого значения указывается как
void. - Спецификатор доступа необязателен и определяет область видимости метода. Например, метод может быть закрытым, защищенным и т.д.
- Модификатор необязателен и определяет тип доступа к методу. Методы могут быть статическими, виртуальными, закрытыми и т.д.
- Тело метода представляет собой список инструкций, необходимых для выполнения задачи методом. Оно заключено в фигурные скобки.
Где мы встречаемся с методами C# впервые? Вспомните часть про “Базовую структуру программы на C#“. Если создать проект консольного приложения без использования оператором верхнего уровня, то вы увидите главный (и пока единственный) метод приложения – Main():
namespace ConsoleApp3
{
internal class Program
{
//вот он - главный метод приложения
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
}
}
}
Разберем этот метод:
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
}
static— это модификатор. О том, что он обозначает, мы поговорим позднее, когда доберемся до работы с классами и объектами в C#.void— тип возвращаемого значения. То есть метод не возвращает ничего.Main— это имя метода.string[] args— это единственный параметр метода — массив строк.
Внутри метода Main()мы используем всего одну инструкцию – вызываем другой метод, который мы уже использовали ни один десяток раз – это метод класса Console WriteLine():
Console.WriteLine("Hello, World!");
и этот метод уже принимает параметр – строку “Hello, World!”. Теперь попробуем создать наш первый метод.
Пример создания пользовательского метода в C#
Метод создается для того, чтобы выполнять единственную возложенную на него задачу. Это может быть большая задача или маленькая, но она должна быть одна и выполняться методом полностью.
Посмотрите ещё раз на исходный код нашего приложения и попробуйте ответить на вопрос: какие действия выполняются в этой программе? Наша программа выполняет три действия:
- Выводит произвольный цветной текст в консоль
- Получает от пользователя данные (числа)
- Суммирует два числа
Все эти три действия мы можем оформить в виде трех методов.
Пользовательский метод с параметрами и без возвращаемого результата
Первый метод – вывод произвольного цветного текста в консоль. Снова попробуем ответить на вопрос: какие данные требуются для вывода цветного текста в консоль? Первое – это сам текст, который необходимо вывести. Второе – цвет текста. Вот эти данные и будут параметрами метода (без них метод не сможет выполнить свою задачу). Далее, должен ли наш метод что-то возвращать в программу? В данном случае, ответ – нет, не должен. Наш метод выводит текст в консоль и всё. Следовательно, определяем тип возвращаемого результата как voidТеперь оформим наш первый метод в C#. Изменим код приложения, добавив в конец файла следующий код:
void PrintColorText(ConsoleColor color, string text)
{
ConsoleColor oldColor = Console.ForegroundColor;
Console.ForegroundColor = color;
Console.WriteLine(text);
Console.ForegroundColor = oldColor;
}
PrintColorText– это имя нашего метода. Разберемся, что мы здесь делаем. Первое – мы запоминаем текущий цвет текста в консоли:
ConsoleColor oldColor = Console.ForegroundColor;
и в конце работы метода возвращаем этот цвет:
Console.ForegroundColor = oldColor;
Если этого не сделать, то после выполнения метода, цвет текста в консоли останется таким, как мы его определим в параметрах нашего метода, что может привести в дальнейшем к проблемам понимания того, почему вдруг цвет текста стал, например, красным, хотя в основной программе мы его не меняли?
Далее, мы назначаем новый цвет текста и выводим его в консоль:
Console.ForegroundColor = color; Console.WriteLine(text);
Как теперь воспользоваться нашим методом в приложении? Вызов метода осуществляется по его имени. При этом, все значения обязательных параметров метода указываются в круглых скобках после названия. То есть уже сейчас мы можем изменить код нашей программы следующим образом:
PrintColorText(ConsoleColor.DarkBlue, "Привет, программист!\r\nКод этого приложения прекрасно работает");
PrintColorText(ConsoleColor.DarkGreen, "И даже пишет в консоль текст разными цветами\r\n\"И считает суммы чисел");
Console.Write("Введите первое число ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Введите второе число ");
int b = Convert.ToInt32(Console.ReadLine());
Console.WriteLine($"Сумма {a} + {b} = {a + b}");
PrintColorText(ConsoleColor.DarkGreen, "Видишь?");
PrintColorText(ConsoleColor.DarkMagenta, "Давай попробуем ещё раз?");
Console.Write("Введите первое число ");
a = Convert.ToInt32(Console.ReadLine());
Console.Write("Введите второе число ");
b = Convert.ToInt32(Console.ReadLine());
Console.WriteLine($"Сумма {a} + {b} = {a + b}");
PrintColorText(ConsoleColor.DarkGreen, "И ещё раз");
Console.Write("Введите первое число ");
a = Convert.ToInt32(Console.ReadLine());
Console.Write("Введите второе число ");
b = Convert.ToInt32(Console.ReadLine());
Console.Write($"Сумма {a} + {b} = {a + b}");
PrintColorText(ConsoleColor.DarkBlue, "Отличная программа!");
PrintColorText(ConsoleColor.Red, "Только трудно поддерживаемая и содержит много повторяющегося кода!");
PrintColorText(ConsoleColor.Red, "Для улучшения нам потребуются методы");
Console.ReadKey();
void PrintColorText(ConsoleColor color, string text)
{
ConsoleColor oldColor = Console.ForegroundColor;
Console.ForegroundColor = color;
Console.WriteLine(text);
Console.ForegroundColor = oldColor;
}
Обратите внимание – код приложения стал короче, а, дав методу осмысленное название (PrintColorText) мы можем понять что и как делает метод, даже не заглядывая в его код, например по строке:
PrintColorText(ConsoleColor.DarkGreen, "Видишь?");
мы понимаем, что будет напечатана строка текста темно-зеленым цветом. Теперь мы отчётливо видим следующий повтор кода в нашем приложении:
Console.Write("Введите первое число ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Введите второе число ");
int b = Convert.ToInt32(Console.ReadLine());
Console.WriteLine($"Сумма {a} + {b} = {a + b}");
Здесь мы запрашиваем два числа, суммируем их и выводим результат в консоль. Разобьем этот код на два метода – запрос данных и суммирование чисел, а для вывода результата, воспользуемся уже созданным нами методом.
Пользовательский метод с параметрами и возвращаемым результатом
Посмотрим на вот эти строки кода:
Console.Write("Введите первое число ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Введите второе число ");
int b = Convert.ToInt32(Console.ReadLine());
Здесь воспроизводится дважды один и тот же порядок действий:
- Вывести в консоль предложение пользователю задать число
- Считать ввод пользователя (
Console.ReadLine()) - Конвертировать строку в число (
Convert.ToInt32(Console.ReadLine())) - Присвоить полученное число какой-то переменной
Исходя из этих действий, попробуем определить параметры нашего нового метода. Что изменяется от одного запроса данных к другому запросу данных? Меняется только строка. В первом запросе – это строка “Введите первое число “, во втором запросе – “Введите второе число “. Следовательно, имеет смысл текст запроса сделать параметром метода. Далее, ответим на вопрос: в чем заключается конечная задача нашего метода? Она заключается в том, чтобы вернуть число, которое мы можем потом присвоить какой-либо переменной. Жирным выделен ключевой момент – наш метод должен возвращать число и, следовательно, тип возвращаемого методом результата будет уже не voidРаз наша программа складывает целый числа, то наш новый метод можно представить следующим образом:
int QueryNumber(string query)
{
Console.Write(query);
return Convert.ToInt32(Console.ReadLine());
}
Обратите внимание на ключевое слово returnв нашем методе. Мы уже встречались с ним, когда рассматривали управляющие операторы. В методах C# это ключевое слово играет точно такую же роль – returnзавершает выполнение метода, а, если после ключевого слова находится какое-либо выражение, то передает результат этого выражения в качестве результата метода. То есть, в нашем случае, метод вернет число, полученное из строки, которую ввел пользователь.
Применим этот метод в нашем приложении:
PrintColorText(ConsoleColor.DarkBlue, "Привет, программист!\r\nКод этого приложения прекрасно работает");
PrintColorText(ConsoleColor.DarkGreen, "И даже пишет в консоль текст разными цветами\r\n\"И считает суммы чисел");
int a = QueryNumber("Введите первое число ");
int b = QueryNumber("Введите второе число ");
Console.WriteLine($"Сумма {a} + {b} = {a + b}");
PrintColorText(ConsoleColor.DarkGreen, "Видишь?");
PrintColorText(ConsoleColor.DarkMagenta, "Давай попробуем ещё раз?");
a = QueryNumber("Введите первое число ");
b = QueryNumber("Введите второе число ");
Console.WriteLine($"Сумма {a} + {b} = {a + b}");
PrintColorText(ConsoleColor.DarkGreen, "И ещё раз");
a = QueryNumber("Введите первое число ");
b = QueryNumber("Введите второе число ");
Console.Write($"Сумма {a} + {b} = {a + b}");
PrintColorText(ConsoleColor.DarkBlue, "Отличная программа!");
PrintColorText(ConsoleColor.Red, "Только трудно поддерживаемая и содержит много повторяющегося кода!");
PrintColorText(ConsoleColor.Red, "Для улучшения нам потребуются методы");
Console.ReadKey();
int QueryNumber(string query)
{
Console.Write(query);
return Convert.ToInt32(Console.ReadLine());
}
void PrintColorText(ConsoleColor color, string text)
{
ConsoleColor oldColor = Console.ForegroundColor;
Console.ForegroundColor = color;
Console.WriteLine(text);
Console.ForegroundColor = oldColor;
}
Обратите внимание – так как наш метод возвращает в качестве результата целое число, то мы можем сразу присваивать переменным значение, возвращаемое методом, например:
int a = QueryNumber("Введите первое число ");
Что касается вывода информации о сумме двух чисел, то здесь мы можем оставить все как есть или можно сделать, например, вывод ответа другим цветом – для этого у нас уже определен метод PrintColorText(). Также, мы можем определить отдельный метод для суммирования двух чисел, например:
int Sum(int first, int second)
{
return first + second;
}
И применить этот метод вот так:
PrintColorText(ConsoleColor.Yellow, $"Сумма {a} + {b} = {Sum(a, b)}");
В этом случае программа будет действовать следующим образом:
- Рассчитает сумму двух чисел:
Sum(a, b) - Сформирует строку текста, то есть выполнит вот эту часть кода:
$"Сумма {a} + {b} = {Sum(a, b)}" - Вызовет метод
PrintColorText()и в консоли мы увидим ответ, написанный желтым цветом
Вот как теперь будет выглядеть наша программа, в которой определены три пользовательских метода C#:
PrintColorText(ConsoleColor.DarkBlue, "Привет, программист!\r\nКод этого приложения прекрасно работает");
PrintColorText(ConsoleColor.DarkGreen, "И даже пишет в консоль текст разными цветами\r\n\"И считает суммы чисел");
int a = QueryNumber("Введите первое число ");
int b = QueryNumber("Введите второе число ");
PrintColorText(ConsoleColor.Yellow, $"Сумма {a} + {b} = {Sum(a, b)}");
PrintColorText(ConsoleColor.DarkGreen, "Видишь?");
PrintColorText(ConsoleColor.DarkMagenta, "Давай попробуем ещё раз?");
a = QueryNumber("Введите первое число ");
b = QueryNumber("Введите второе число ");
PrintColorText(ConsoleColor.Yellow, $"Сумма {a} + {b} = {Sum(a, b)}");
PrintColorText(ConsoleColor.DarkGreen, "И ещё раз");
a = QueryNumber("Введите первое число ");
b = QueryNumber("Введите второе число ");
PrintColorText(ConsoleColor.Yellow, $"Сумма {a} + {b} = {Sum(a, b)}");
PrintColorText(ConsoleColor.DarkBlue, "Отличная программа!");
PrintColorText(ConsoleColor.Red, "Только трудно поддерживаемая и содержит много повторяющегося кода!");
PrintColorText(ConsoleColor.Red, "Для улучшения нам потребуются методы");
Console.ReadKey();
int Sum(int first, int second)
{
return first + second;
}
int QueryNumber(string query)
{
Console.Write(query);
return Convert.ToInt32(Console.ReadLine());
}
void PrintColorText(ConsoleColor color, string text)
{
ConsoleColor oldColor = Console.ForegroundColor;
Console.ForegroundColor = color;
Console.WriteLine(text);
Console.ForegroundColor = oldColor;
}
Теперь наша программа стала короче, понятнее, а её поддержка стала намного проще. Вывод в программе теперь будет следующий:
Также, в C# методы могут быть без параметров и без возвращаемого результата или без параметров, но с возвращаемым результатом. Рассмотрим такие виды методов и немного улучшим нашу программу.
Пользовательский метод без параметров и без возвращаемого результата
Метод C# без параметров и без возвращаемого результата может выполнять какую-либо полезную для нас работу и, при этом, нам не требуется получать от этого метода никаких данных. Например, мы можем написать вот такой метод:
void PrintLine()
{
for (int i=0; i < Console.BufferWidth; i++)
{
if (i % 2 == 0)
Console.Write('+');
else
Console.Write('-');
}
}
Этот метод ничего не принимает в качестве параметров и ничего не возвращает, но делает полезную работу – “рисует” линию из знаков “плюс” и “минус” на всю ширину доступной для печати области окна консоли. Например, несколько вызовов этого метода в нашей программе могут добавить в консоль вот такие “элементы декора”
Пользовательский метод без параметров, но с возвращаемым результатом
Такие методы также могут использоваться при разработке программ. Например, метод может производить какие-либо расчёты по известным ему значениям и выдавать результат:
int GetConsolSquare()
{
return Console.WindowWidth * Console.WindowHeight;
}
Этот метод использует доступные ему данные (ширину окна консоли в столбцах и высоту консоли в строках) и рассчитывает площадь – сколько всего символов можно уместить в окне консоли при текущих размерах окна. Например, мы можем использовать этот метод в нашей программе:
Сокращенная запись методов в C#
Если методы выполняет всего одну операцию, то допускается сокращенная запись. Например, наш метод GetConsolSquare() выполняет всего одну операцию. В этом случае, мы можем сократить запись метода следующим образом:
int GetConsolSquare() => Console.WindowWidth * Console.WindowHeight;
Так как метод выполняется всего одну инструкцию, то за списком параметров ставится специальный оператор => и далее пишется единственная инструкция метода.
Подведем итог
Методы в C# используются для того, чтобы сделать код более лаконичным, понятным и легким в поддержке. Метод выполняет возложенную на него задачу (желательно – одну единственную) и может возвращать или не возвращать результат. Для работы методов могут требоваться какие-либо дополнительные данные – в этом случае после названия метода в круглых скобках указываются по порядку через запятую типы и имена параметров метода.
Домашнее задание №15
Создайте метод Power(), вычисляющий степень целого числа и используйте её в консольном приложении C#. Программа должна последовательно запросить число, степень, в которую необходимо возвести это число и вывести результат расчёта.