Язык программирования C#9 и платформа .NET5
Например, если вы хотите получить значение для
в предыдущем примере, но остальные два параметра вас не волнуют, тогда можете написать такой код:int// Здесь будет получено значение только для а;// значения для других двух параметров игнорируются.FillTheseValues(out int a, out _, out _);Обратите внимание, что вызываемый метод по-прежнему выполняет работу, связанную с установкой значений для всех трех параметров; просто последние два параметра отбрасываются, когда происходит возврат из вызова метода.
Модификатор out в конструкторах и инициализаторах (нововведение в версии 7.3)
В версии C# 7.3 были расширены допустимые местоположения для использования параметра
. В дополнение к методам параметры конструкторов, инициализаторы полей и свойств, а также конструкции запросов можно декорировать модификаторомout. Примеры будут представлены позже в главе.outИспользование модификатора ref
А теперь посмотрим, как в C# используется модификатор
. Ссылочные параметры необходимы, когда вы хотите разрешить методу манипулировать различными элементами данных (и обычно изменять их значения), которые объявлены в вызывающем коде, таком как процедура сортировки или обмена.refОбратите внимание на отличия между ссылочными и выходными параметрами.
• Выходные параметры не нуждаются в инициализации перед передачей методу. Причина в том, что метод до своего завершения обязан самостоятельно присваивать значения выходным параметрам.
• Ссылочные параметры должны быть инициализированы перед передачей методу. Причина связана с передачей ссылок на существующие переменные. Если начальные значения им не присвоены, то это будет равнозначно работе с неинициализированными локальными переменными.
Давайте рассмотрим применение ключевого слова
на примере метода, меняющего местами значения двух переменных типаref(естественно, здесь мог бы использоваться любой тип данных, включаяstring,int,boolи т.д.):float// Ссылочные параметры.public static void SwapStrings(ref string s1, ref string s2){string tempStr = s1;s1 = s2;s2 = tempStr;}Метод
можно вызвать следующим образом:SwapStrings()Console.WriteLine("***** Fun with Methods *****");string str1 = "Flip";string str2 = "Flop";Console.WriteLine("Before: {0}, {1} ", str1, str2); // ДоSwapStrings(ref str1, ref str2);Console.WriteLine("After: {0}, {1} ", str1, str2); // ПослеConsole.ReadLine();Здесь вызывающий код присваивает начальные значения локальным строковым данным (
иstr1). После вызова методаstr2строкаSwapStrings()будет содержать значениеstr1, а строка"Flop"— значениеstr2:"Flip"Before: Flip, FlopAfter: Flop, FlipИспользование модификатора in (нововведение в версии 7.2)
Модификатор
обеспечивает передачу значения по ссылке (для типов значений и ссылочных типов) и препятствует модификации значений в вызываемом методе. Это четко формулирует проектный замысел в коде, а также потенциально снижает нагрузку на память. Когда параметры типов значений передаются по значению, они (внутренне) копируются вызываемым методом. Если объект является большим (вроде крупной структуры), тогда добавочные накладные расходы на создание копии для локального использования могут оказаться значительными. Кроме того, даже когда параметры ссылочных типов передаются без модификатора, в вызываемом методе их можно модифицировать. Обе проблемы решаются с применением модификатораin.inВ рассмотренном ранее методе
есть две строки кода, которые изменяют параметры, но не влияют на значения для вызывающего метода. Влияние на значения отсутствует из-за того, что методAdd()создает копию переменныхAdd()ихс целью локального использования. Пока вызывающий метод не имеет неблагоприятных побочных эффектов, но что произойдет, если бы код методаубыл таким, как показано ниже?Add()static int Add2(int x,int y){x = 10000;y = 88888;int ans = x + y;return ans;}В данном случае метод возвращает значение
независимо от переданных ему чисел, что очевидно представляет собой проблему. Чтобы устранить ее, код метода понадобится изменить следующим образом:98888static int AddReadOnly(in int x,in int y){// Ошибка CS8331 Cannot assign to variable 'in int'// because it is a readonly variable// He удается присвоить значение переменной in int,// поскольку она допускает только чтение// х = 10000;// у = 88888;int ans = x + y;return ans;}Когда в коде предпринимается попытка изменить значения параметров, компилятор сообщит об ошибке CS8331, указывая на то, что значения не могут быть изменены из-за наличия модификатора
.in