ref и out в C#

ref и out в C#

Всем доброго времени суток, на связи Алексей Гулынин. В прошлой статье мы узнали про перегруженные методы в C#. В данной статье я бы хотел поговорить про ключевые слова ref и out в C#. Использование этих ключевых слов приводит к тому, что параметр начинает передаваться не по значению, а по ссылке. Ключевое слово out обозначает почти то же самое, что и ref. Параметр, перед которым указываются данные операторы, тоже передаётся по ссылке, т.е. в переменной хранится адрес этого параметра. В чем разница же между ref и out? Разница в том, что out позволяет вам передать ссылку на переменную неинициализированную, а ref — только на инициализированную.

Давайте на примере разберем, что это значит. Создадим метод, который будет принимать числовой параметр. В данном методе этот параметр будем увеличивать и выводить значение. В методе Main() создадим параметр с этим же именем и будем также выводить его значение:

static void Main(string[] args)
{
	int param = 10;
	testMethod(param); //Выйдет значение = 11
	Console.WriteLine("Значение переменной param в методе Main = {0}", param); //Выйдет значение = 10
	Console.ReadLine();
}
static void testMethod(int param)
{
	param++;
	Console.WriteLine("Значение переменной param в методе testMethod = {0}", param);
}

Во втором случае вышло 10, потому что int — это ValueType (это когда параметр передаётся по значению), это значит, что при выполнении команды testMethod(param) метод testMethod() будет работать с копией переменной param (в данный момент происходит копирование переменной в стеке), что никак не повлияет на переменную param, которая была объявлена в методе Main(). Модифицируем наш код, добавив оператор ref перед переменной в методе testMethod(). Обратите внимание, что при вызове данного метода нужно также ставить оператор ref:

static void Main(string[] args)
{
	int param = 10;
	testMethod(ref param); //Выйдет значение = 11
	Console.WriteLine("Значение переменной param в методе Main = {0}", param); //Выйдет значение = 11
	Console.ReadLine();
}
static void testMethod(ref int param)
{
	param++;
	Console.WriteLine("Значение переменной param в методе testMethod = {0}", param);
}

Теперь программа в обоих случаях выводит 11. Тут дело в том, что мы в стек (это область памяти в пространстве адресов) загоняем ссылку на область памяти, где находится переменная param, и в методе testMethod() мы уже работаем не с копией, а с тем же самым параметром param, что и в методе Main(). Те изменения, которые мы провели с переменной param в методе testMethod() будут видны и снаружи (за областью видимости метода).

Внесем изменения в наш код. Просто объявим переменную param, но не будем её инициализировать, т.е. вместо строки int param = 10; запишем int param;. Компилятор старается контролировать использование неинициализированных переменных вы даст ошибку в этом случае. Мы пытаемся переменную, которая не содержит никаких значений, передать в метод и там с ней выполнять определенные действия, но так делать нельзя. А что делать если инициализация переменной выполняется как раз в этом методе?

В этом случае как раз и используют out:

static void Main(string[] args)
{
	int param;
	testMethod(out param); //Выйдет значение = 11
	Console.WriteLine("Значение переменной param в методе Main = {0}", param); //Выйдет значение = 11
	Console.ReadLine();
}
static void testMethod(out int param)
{
	param = 10;
	param++;
	Console.WriteLine("Значение переменной param в методе testMethod = {0}", param);
}

Теперь в методе testMethod() обязательно нужно проинициализировать переменную param.

В данной небольшой статье вы узнали про ключевые слова ref и out в C#.

На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.


Комментарии:

Один комментарий

  • Читаю троелсона , очень сложно объяснил про ref and out , но тут реально легко понимается , спасибо за статью , почитаю у вас еще

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *