Параметры методов
В прошлой теме был определен метод SayHello
, который выводит на консоль некоторое сообщение:
void SayHello()
{
Console.WriteLine("Hello");
}
SayHello(); // Hello
Но минусом подобного метода является то, что он выводит одно и то же сообщение. И было бы неплохо, если бы мы могли бы динамически определять, какое сообщение будет выводить метод на экран, то есть передать из вне в метод это сообщение. Для этого в языке C# мы можем использовать параметры.
Параметры позволяют передать в метод некоторые входные данные. Параметры определяются через запятую в скобках после названия метода в виде:
тип_метода имя_метода (тип_параметра1 параметр1, тип_параметра2 параметр2, ...)
{
// действия метода
}
Определение параметра состоит из двух частей: сначала идет тип параметра и затем его имя.
Например, определим метод PrintMessage
, который получает извне выводимое сообщение:
void PrintMessage(string message)
{
Console.WriteLine(message);
}
PrintMessage("Hello work"); // Hello work
PrintMessage("Hello IT-Мозг"); // Hello IT-Мозг
PrintMessage("Hello C#"); // Hello C#
Здесь метод PrintMessage()
принимает один параметр, который называется message
и имеет тип string
.
Чтобы выполнить метод, который имеет параметры, при вызове после имени метода в скобках ему передаются значения для его параметров, например:
PrintMessage("Hello work");
Здесь параметру message
передается строка "Hello work"
. Значения, которые передаются параметрам, еще называются аргументами. То есть передаваемая строка "Hello work"
в данном случае является аргументом.
Иногда можно встретить такие определения как формальные параметры и фактические параметры. Формальные параметры - это собственно параметры метода (в данном случае message), а фактические параметры - значения, которые передаются формальным параметрам. То есть фактические параметры - это и есть аргументы метода.
Определим еще один метод, который складывает два числа:
void Sum(int x, int y)
{
int result = x + y;
Console.WriteLine($"{x} + {y} = {result}");
}
Sum(10, 15); // 10 + 15 = 25
Метод Sum
имеет два параметра: x
и y
. Оба параметра представляют тип int
. Поэтому при вызове данного метода нам обязательно надо передать на место этих параметров два числа. Внутри метода вычисляется сумма переданных чисел и выводится на консоль.
При вызове метода Sum
значения передаются параметрам по позиции. Например, в вызове Sum(10, 15)
число 10
передается параметру x
, а число 15
- параметру y
.
Также параметры могут использоваться в сокращенной версии метода:
void Sum(int x, int y) => Console.WriteLine($"{x} + {y} = { x + y }");
Sum(10, 15); // 10 + 15 = 25
Передаваемые параметру значения могут представлять значения переменных или результат работы сложных выражений, которые возвращают некоторое значение:
void Sum(int x, int y) => Console.WriteLine($"{x} + {y} = { x + y }");
int a = 10, b = 15, c = 6;
Sum(a, b); // 10 + 15 = 25
Sum(3, c); // 3 + 6 = 9
Sum(14, 4 + c); // 14 + 10 = 24
Если параметрами метода передаются значения переменных, то таким переменным должно быть присвоено значение. Например, следующая программа не скомпилируется:
void Sum(int x, int y)
{
Console.WriteLine($"{x} + {y} = { x + y }");
}
int a;
int b = 15;
Sum(a, b); // ! Ошибка
Соответствие парамеров и аргументов по типу данных
При передаче значений параметрам важно учитывать тип параметров: между аргументами и параметрами должно быть соответствие по типу. Например:
void PrintPerson(string name, int age)
{
Console.WriteLine($"Name: {name} Age: {age}");
}
PrintPerson("Tom", 24); // Name: Tom Age: 24
В данном случае первый параметр метода PrintPerson()
представляет тип string
, поэтому при вызове метода мы должны передать этому параметру значение типа string
, то есть строку. Второй параметр представляет тип int
, поэтому должны передать ему целое число, которое соответствует типу int
.
PrintPerson("Tom", 24);
Также мы можем передать параметрам значения тех типов, которые автоматически могут быть преобразованы в тип параметров. Например:
void PrintPerson(string name, int age)
{
Console.WriteLine($"Name: {name} Age: {age}");
}
byte b = 37;
PrintPerson("Tom", b); // Name: Tom Age: 37
Здесь параметру типа int
передается значение типа byte
, но компилятор может автоматически преобразовать значение типа byte
к тиу int
. Поэтому здесь ошибки не возникнет. Какие преобразования типов могут быть выполнены автоматически, рассматривалось в одной из предыдущих тем: Преобразования базовых типов данных.
Данные других типов мы передать параметров не можем. Например, следующий вызов метода PrintPerson
будет ошибочным:
PrintPerson(45, "Bob"); // Ошибка! несоответствие значений типам параметров
Необязательные параметры
По умолчанию при вызове метода необходимо предоставить значения для всех его параметров. Но C# также позволяет использовать необязательные параметры. Для таких параметров нам необходимо объявить значение по умолчанию. Также следует учитывать, что после необязательных параметров все последующие параметры также должны быть необязательными:
void PrintPerson(string name, int age = 1, string company = "Undefined")
{
Console.WriteLine($"Name: {name} Age: {age} Company: {company}");
}
Здесь параметры age
и company
являются необязательными, так как им присвоены значения. Поэтому при вызове метода мы можем не передавать для них данные:
void PrintPerson(string name, int age = 1, string company = "Undefined")
{
Console.WriteLine($"Name: {name} Age: {age} Company: {company}");
}
PrintPerson("Tom", 37, "Microsoft"); // Name: Tom Age: 37 Company: Microsoft
PrintPerson("Tom", 37); // Name: Tom Age: 37 Company: Undefined
PrintPerson("Tom"); // Name: Tom Age: 1 Company: Undefined
Консольный вывод программы:
Name: Tom Age: 37 Company: Microsoft
Name: Tom Age: 37 Company: Undefined
Name: Tom Age: 1 Company: Undefined
Именованные параметры
В предыдущих примерах при вызове методов значения для параметров передавались в порядке объявления этих параметров в методе. То есть аргументы передавались параметрам по позиции. Но мы можем нарушить подобный порядок, используя именованные параметры:
void PrintPerson(string name, int age = 1, string company = "Undefined")
{
Console.WriteLine($"Name: {name} Age: {age} Company: {company}");
}
PrintPerson("Tom", company:"Microsoft", age: 37); // Name: Tom Age: 37 Company: Microsoft
PrintPerson(age:41, name: "Bob"); // Name: Bob Age: 41 Company: Undefined
PrintPerson(company:"Google", name:"Sam"); // Name: Sam Age: 1 Company: Google
Для передачи значений параметрам о имени при вызове метода указывается имя параметра и через двоеточие его значение: name:"Tom"
.
Консольный вывод программы:
Name: Tom Age: 37 Company: Microsoft
Name: Bob Age: 41 Company: Undefined
Name: Sam Age: 1 Company: Google