Мегаобучалка Главная | О нас | Обратная связь


Передача параметров по ссылке и модификатор ref



2019-11-13 195 Обсуждений (0)
Передача параметров по ссылке и модификатор ref 0.00 из 5.00 0 оценок




Функции

В отличие от процедур функции возвращают определенное значение. Например, определим пару функций:

 

int Factorial() {

return 1;

}

 

string Hello() {

return "Hell to World";

}

 

В функции в качестве типа возвращаемого значения вместоvoidиспользуется любой другой тип. В данном случае типint. Функции также отличаются тем, что мы обязательно должны использовать операторreturn, после которого ставится возвращаемое значение.

Также стоит отметить, что возвращаемое значение всегда должно иметь тот же тип, что значится в определении функции. То есть если у нас функция возвращает значение типаint, поэтому после оператора return стоит число 1 – которое неявно является объектом типаint.

 

Использование методов в программе

 

Определив методы, мы можем использовать их в программе. Чтобы вызвать метод в программе, надо указать имя метода, а после него в скобках значения для его параметров:

 

public static void Main(string[] args) {

string message = Hello(); // вызов первого метода

Console.WriteLine(message);

Sum(); // вызов второго метода

Console.ReadLine();

}

 

public static string Hello() {

return "Hell to World!";

}

 

public static void Sum() {

int x = 2;

int y = 3;

Console.WriteLine("{0} + {1} = {2}", x, y, x+y);

}

 

Здесь определены два метода. Первый метод Hello возвращает значение типаstring. Поэтому мы можем присвоить это значение какой-нибудь переменной типа string:string message = Hello();

Второй метод - процедура Sum – просто складывает два числа и выводит результат на консоль.

 

Ссылочные типы и типы значений

В языке C# все типы данных делятся на две категории – ссылочные типы, и типы значений. Они отличаются способом хранения в памяти, производительностью и другим.

 

Типы значений

 

Эту категорию также называют структурными типами. Типы значений хранятся в стеке. Стек - это область памяти, которая используется для передачи параметров в методы и хранения определенных в пределах методов локальных переменных. Данные переменной типа значения хранятся в самой переменной.

К типам значений относятся:

- Целочисленные типы (byte, sbyte, char, short, ushort, int, uint, long, ulong);

- Типы с плавающей запятой (float, double);

- Типdecimal;

- Типbool;

- Пользовательские структуры (struct);

- Перечисления (enum).

 

Код ниже показывает, что при присвоении значения одной переменной значимого типа другой, дальнейшее изменение одной из переменных не влияет на другую. Так потому, что хранение данных значимого типа происходит в самой переменной:

 

static void Main(string[] args) {

int a = 1;

int b = 2;

b = a;

a = 3;

Console.WriteLine(a); // 3

Console.WriteLine(b); // 1

{

 

Ссылочные типы

Переменная ссылочного типа содержит не данные, а ссылку на них. Сами данные в этом случае уже хранятся в куче. Куча - это область памяти, в которой размещаются управляемые объекты, и работает сборщик мусора. Сборщик мусора освобождает все ресурсы и объекты, которые уже не нужны.

К ссылочным типам относятся:

- Классы (class);

- Интерфейсы (interface);

- Делегаты (delegate);

- Типobject;

- Типstring.


 

В коде ниже был создан простой класс, в котором есть одно поле типа int. Дальше была проделана такая же процедура, как и в случае выше, только результат уже другой. После присвоения одного объекта другому, они стали указывать на одну и ту же область памяти (меняем b – меняется и a):

 

class Test {

public int x;

}

 

class Program {

static void Main(string[] args) {

   Test a = new Test();

   Test b = new Test();

   a.x = 1;

   b.x = 2;

   b = a; // присвоение ссылки

   b.x = 3;

   Console.WriteLine(a.x); // 3

   Console.WriteLine(b.x); // 3

}

}

Параметры метода

Теперь посмотрим, как применяются параметры. Параметры представляют собой переменные, которые определяются в сигнатуре метода и создаются при его вызове.

Существует два способа передачи параметров в метод в языке C#: по значению и по ссылке.

Наиболее простой способ передачи параметров представляет передача по значению:

 

static int Sum(int x, int y) {

return x + y;

}

 

И при вызове этого метода в программе нам обязательно надо передать на место параметров значения, которые соответствуют типу параметра. Данные значения еще называютаргументами:

 

static void Main(string[] args) {

int x = 10;

int z = Sum(x, 15);

Console.WriteLine(z);

Console.ReadLine();

}

 


Передача параметров по ссылке и модификатор ref

 

При передаче параметров по ссылке перед параметрами используется модификаторref:

 

static void Main(string[] args) {

int x = 10;

int y = 15;

Addition(ref x, y); // вызов метода

Console.WriteLine(x);

Console.ReadLine();

}

 

// определение метода

static void Addition(ref int x, int y) {

x += y;

}

 

В чем отличие двух способов передачи параметров? При передаче по значению метод получает не саму переменную, а ее копию. А при передаче параметра по ссылке метод получает адрес переменной в памяти. И, таким образом, если в методе изменяется значение параметра, передаваемого по ссылке, то также изменяется и значение переменной, которая передается на его место.


 

Пример:

 

static void Main(string[] args) {

//Начальные значения переменных a и b

int a = 5;

int b = 6;

Console.WriteLine("Начальное значение переменной a = {0}", a);

//Передача переменных по значению

//После выполнения этого кода по-прежнему a = 5, так как мы передали лишь

   ее копию

AdditionVal(a, b);

Console.WriteLine("Переменная a после передачи по значению равна = {0}",

   a);

//Передача переменных по ссылке

//После выполнения этого кода a = 11, так как мы передали саму переменную

   AdditionRef(ref a, b);

Console.WriteLine("Переменная a после передачи ссылке по значению равна =

   {0}", a);

Console.ReadLine();

}

 

// передача по ссылке

static void AdditionRef(ref int x, int y) {

x = x + y;

Console.WriteLine("x + y = {0}", x);

}

 

// передача по значению

static void AdditionVal(int x, int y) {

x = x + y;

Console.WriteLine("x + y = {0}", x);

}

 

Здесь в методе Main у нас есть две переменные: a и b. Имеется два метода, которые принимают два параметра: x и y. В обоих методах значение параметра x приравнивается сумме x и y.

В методе Main мы подставляем на место параметров x и y переменные a и b соответственно. В первом случае переменная передается по значению, то есть передается копия этой переменной, и она не изменяется. Во втором случае мы передаем указатель на эту переменную в памяти. И так как в методеAdditionRefзначение параметра x изменяется, то передаваемая на его место переменная a тоже изменяет свое значение.

Обратите внимание, что модификаторrefуказывается, как при объявлении метода, так и при его вызове в методе Main.

 


Модификатор out

 

Выше мы использовали входные параметры. Но параметры могут быть также выходными. Чтобы сделать параметр выходным, перед ним ставится модификаторout:

 

static void Sum(int x, int y, out int a) {

a = x + y;

}

 

Здесь результат возвращается не через операторreturn, а через выходной параметр. Использование в программе:

 

static void Main(string[] args) {

int x = 10;

int z;

Sum(x, 15, out z);

Console.WriteLine(z);

Console.ReadLine();

}

 

Причем, как и в случае сref ключевое слово out используется как при определении метода, так и при его вызове.

Также обратите внимание, что методы, использующие такие параметры, обязательно должны присваивать им определенное значение. То есть следующий код будет недопустим, так как в нем для out-параметра не указано никакого значения:

 

static void Sum(int x, int y, out int a) {

Console.WriteLine(x+y);

}

 

Прелесть использования подобных параметров состоит в том, что по сути мы можем вернуть из метода не один вариант, а несколько.

Пример:

 

static void Main(string[] args) {

int x = 10;

int area;

int perimetr;

GetData(x, 15, out area, out perimetr);

Console.WriteLine("Площадь : " + area);

Console.WriteLine("Периметр : " + perimetr);

Console.ReadLine();

}

 

static void GetData(int x, int y, out int area, out int perim) {

area= x * y;

perim= (x + y)*2;

}

 

Здесь у нас есть метод GetData, который, допустим, принимает стороны прямоугольника. А два выходных параметра мы используем для подсчета площади и периметра прямоугольника.

По сути, как и в случае с ключевым словомref, ключевое словоoutприменяется для для передачи аргументов по ссылке. Однако в отличие от ref для переменных, которые передаются с ключевым словам out, не требуется инициализация. И кроме того, вызываемый метод должен обязательно присвоить им значение.

Стоит отметить, что в версии C# 7.0 (Visual Studio 2017) можно определять переменные в непосредственно при вызове метода. То есть вместо:

 

int x = 10;

int area;

int perimetr;

GetData(x, 15, out area, out perimetr);

Console.WriteLine("Площадь : " + area);

Console.WriteLine("Периметр : " + perimetr);

 

Мы можем написать:

 

int x = 10;

GetData(x, 15, out int area, out int perimetr);

Console.WriteLine("Площадь : " + area);

Console.WriteLine("Периметр : " + perimetr);

 



2019-11-13 195 Обсуждений (0)
Передача параметров по ссылке и модификатор ref 0.00 из 5.00 0 оценок









Обсуждение в статье: Передача параметров по ссылке и модификатор ref

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Личность ребенка как объект и субъект в образовательной технологии: В настоящее время в России идет становление новой системы образования, ориентированного на вхождение...
Как выбрать специалиста по управлению гостиницей: Понятно, что управление гостиницей невозможно без специальных знаний. Соответственно, важна квалификация...
Как вы ведете себя при стрессе?: Вы можете самостоятельно управлять стрессом! Каждый из нас имеет право и возможность уменьшить его воздействие на нас...
Генезис конфликтологии как науки в древней Греции: Для уяснения предыстории конфликтологии существенное значение имеет обращение к античной...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (195)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.02 сек.)