- •Функции
- •Глобальные переменные
- •Использование параметров и возвращаемых значений Модификаторы параметров методов
- •Входные параметры, представленные значением
- •Выходные параметры, представленные значением
- •Ссылочные параметры, определенные явно
- •Ссылочные параметры, определенные неявно
- •Перегрузка функций
- •Передача методу переменного количества аргументов
- •Функция main(): аргументы командной строки
Входные параметры, представленные значением
При передаче именованного параметра он передается по значению, т.е. внутри метода создается копия подключенных данных и метод работает с этой копией. Оригинальные данные клиента метода не меняются и вызывающая сторона не увидит выполненных изменений. Это самый безопасный способ передачи, когда по исходным данным нужно получить какой-то результат, оставив сами данные без изменений.
//параметры и возвращаемые значения вместо глобальных данных
using System;
namespace Func03
{
class Program
{
/*
static void ShowDouble(ref int val)
{
val *= 2;
Console.WriteLine("Удвоенное значение val = {0}", val);
}
static void Main(string[] args)
{
int val = 5;
Console.WriteLine("val = {0}", val);
ShowDouble(ref val);
Console.WriteLine("val = {0}", val);
Console.ReadKey();
}
*/
static int val;//глобальная переменная
static int ShowDouble()
{
val *= 2;
Console.WriteLine("Удвоенное значение val = {0}", val);
return val;
}
static void Main()
{
val = 5; // int val = 5;
Console.WriteLine("val = {0}", val);
int nv= ShowDouble();
Console.WriteLine("val = {0}, nv={1}", val,nv);
Console.ReadKey();
}
}
}
Мы видим, что изменение параметров-значений внутри метода не изменяет данных, хранящихся в вызывающей стороне, поскольку метод работает с копиями.
Заметим, что когда методу передается ссылка на объект, то метод всегда работает с внешними данными, то есть с самим объектом.
Выходные параметры, представленные значением
Те параметры-значения, которые планируется изменять внутри метода, следует обозначать как выходные с помощью ключевого слова out. Это требуется делать и в объявлении метода, и в его вызове.
Пометим в предыдущем примере параметр как выходной.
Выполнив измененную программу, мы увидим, что отмеченные как выходные, параметры меняют в вызывающем коде свои значения. Им в клиенте не обязательно присваивать значения, все равно метод их изменит (если перед использованием в клиенте им не присвоить значение, то компилятор выдаст ошибку).
Ссылочные параметры, определенные явно
Явное определение параметра-ссылки выполняется с помощью ключевого слова ref. Это требуется делать и в объявлении метода, и в его вызове.
Ссылки представляют собой адреса участков памяти, где хранятся данные. Если методу передать ссылку на эту память, то он будет работать с самими данными, а не их копиями, как это происходит с передачей параметра по значению. Если ссылке не присвоить конкретный адрес перед ее передачей методу, то сгенерируется ошибка компиляции, поскольку нельзя использовать в методе неинициализированные данные, в том числе и ссылки.
Ссылочные параметры, определенные неявно
Объекты ссылочного типа адресуются в программе ссылками. Их также можно передать методам по значению. Только при этом в методе создается не копия объекта, а копия ссылки (alias - псевдоним), которая будет адресоваться к тому же объекту. Это значит, что метод будет работать с самим переданным объектом, а не с его копией. Но изменение значения самого псевдонима никак не отразится на переданной из клиента ссылке – она в клиенте по-прежнему будет адресоваться к самому объекту.
Если в метод передать ссылку на объект с модификатором ref, тогда в методе окажется адресная переменная самой ссылки (ссылка на ссылку) и смена значения этой адресной переменной изменит значение ссылки, что приведет к адресации на новый объект.
//Перестановка строк
using System;
namespace FuncSwap
{
class Program
{
public static void SwapRef(ref string str1, ref string str2)
{
string tmp = str1;
str1 = str2;
str2 = tmp;
}
static void Main()
{
string string1 = "Первая строка";
string string2 = "Вторая строка";
string str1 = string1;
string str2 = string2;
Console.WriteLine("string -до вызова: \t{0},{1}",string1, string2);
SwapRef(ref string1,ref string2);
Console.WriteLine("- после вызова: \t{0},{1}", string1, string2);
Console.WriteLine("После вызова (str): \t{0},{1}", str1, str2);
Console.ReadLine();
}
}
}
Поскольку строки представляют собой объекты ссылочного типа, то метод обменивает значения ссылок, которые будут адресоваться к новым строкам.
