Модификаторы параметров методов
В C# формальные параметры метода при его объявлении называют просто параметрами, а фактические параметры, передаваемые методу вызывающей стороной (клиентом) при его вызове - аргументами.
В языке C# существуют два типа переменных - типы, характеризуемые значением и ссылочные типы. Переменные типа значения содержат именованные данные(имяопределяет адрес в ОП, где хранится значение) , к которым относятся все числовые типы, структуры и перечисления. Они создаются при компиляции программы и размещаются в стековой области памяти при загрузке программы.
Ссылочные типы содержат адреса участков памяти, создаваемых динамически при выполнении программы, и представляют неименованные данные(имяопределяет адрес в ОП, в которой хранится адрес ячейки со значением).
Таблица 1 . Объекты типа значения и ссылки | ||
Объявление типа | Создание объекта | Альтернативный синтаксис создания объекта |
Встроенный тип - значение | int a; | int a = new int(); |
Пользовательский тип – значение struct MyStruct { public x, y; } | MyStruct point; | MyStruct point = new MyStruct(); |
Пользовательский тип - ссылка class MyClass{ public x, y;} | // Объявили ссылку MyClass point; // Создали и привязали объект point = new MyClass(); | MyClass point = new MyClass(); |
При выполнении операции присваивания в переменные - значения копируются сами данные, в переменные - ссылки копируется адрес расположения данных.
В C# предлагаются модификаторы параметров, которые обеспечивают контроль со стороны компилятора за действиями программиста при вызове этих методов и передаче им фактических аргументов.
Таблица 2 . Модификаторы параметров в C# | |
Модификатор | Описание |
(нет) | Если параметр метода не помечен модификатором, то предполагается передача параметра по значению, т.е. в вызываемый метод передается копия оригинальных данных |
out | Выходной параметр устанавливается вызываемым методом и передается по ссылке. Если вызываемый метод не присвоит выходному параметру значение, то генерируется ошибка компиляции |
params | Позволяет переслать произвольное число аргументов одинакового типа в виде единого параметра (массив параметров). Для любого метода допускается только один модификатор params и только для последнего по порядку следования параметра |
ref | Передается ссылка на данные клиента, которые метод может менять внутри себя. Фактически метод работает с данными, размещенными вне его |
Внутренние (private) методы обычно параметров не имеют, поскольку все объявленные в классе поля видимы внутри методов класса (являются для них глобальными). Параметры нужны для общедоступных (public) методов, с которыми общаются клиенты класса и передают через них новые значения данных. Такие методы называются интерфейсными, включая и конструкторы.
Входные параметры, представленные значением
При передаче именованного параметра он передается по значению, т.е. внутри метода создается копия подключенных данных и метод работает с этой копией. Оригинальные данные клиента метода не меняются и вызывающая сторона не увидит выполненных изменений. Это самый безопасный способ передачи, когда по исходным данным нужно получить какой-то результат, оставив сами данные без изменений.
//параметры и возвращаемые значения вместо глобальных данных
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();
}
}
}
Мы видим, что изменение параметров-значений внутри метода не изменяет данных, хранящихся в вызывающей стороне, поскольку метод работает с копиями.
Заметим, что когда методу передается ссылка на объект, то метод всегда работает с внешними данными, то есть с самим объектом.